Heroku上的Rails应用程序无法写入PostgreSQL数据库,只能读取

我有一个Ruby on Rails应用程序,可以在本地使用sqlite3数据库,并且可以毫无问题地保存和检索记录。

当使用postgresql数据库在http://moviedata.herokuapp.com/上部署到Heroku时,记录不会保存,即使它看起来像日志说的那样。 从db精细读取的记录和数据按预期显示。

添加记录的尾标记日志是:

2012-08-21T19:51:31+00:00 app[web.1]: 2012-08-21T19:51:31+00:00 app[web.1]: 2012-08-21T19:51:31+00:00 app[web.1]: Started POST "/" for 50.53.6.156 at 2012-08-21 19:51:31 +0000 2012-08-21T19:51:31+00:00 app[web.1]: Parameters: {"utf8"=>"✓", "authenticity_token"=>"+BYQLzhrfDkUVW8UaHikHpmtGHxpeQ/yF4VByHh9m1I=", "movie"=>{"title"=>"The Running Man", "description"=>"A documentary about a public execution game show.", "year"=>"1987", "genre"=>"science fiction"}, "commit"=>"Create Movie"} 2012-08-21T19:51:31+00:00 app[web.1]: Processing by MoviesController#index as HTML 2012-08-21T19:51:31+00:00 app[web.1]: Rendered movies/index.html.erb within layouts/application (5.1ms) 2012-08-21T19:51:31+00:00 app[web.1]: Completed 200 OK in 9ms (Views: 6.7ms | ActiveRecord: 0.9ms) 2012-08-21T19:51:31+00:00 heroku[router]: POST moviedata.herokuapp.com/ dyno=web.1 queue=0 wait=0ms service=17ms status=200 bytes=3479 

添加记录后,’heroku pg’命令在postgres数据库中显示相同的行数(11)。

这是我为学习Rails和Heroku平台而构建的简单应用程序。 要重现这一点,只需访问http://moviedata.herokuapp.com/并单击“新电影”,在表单中输入一些垃圾数据,然后点击“创建电影”。 记录应该保存并显示在首页的列表中,但事实并非如此。

为了能够写入postgres数据库,是否有必要打开,配置或激活的东西? 对我来说似乎很奇怪,它可以从中读取但不能写入。 比日志更好的排除故障方法?

本地我使用的是Ruby 1.9.3,Rails,3.2.8,PostgreSQL 9.1.5,SQLite 3.7.9,Heroku Toolbelt 2.30.3。

编辑/更新:我切换本地版本使用psql。 它也遇到了未保存记录的相同问题。 将用户设置为log_statement =’all’/var/log/postgresql/posgresql-9.1.main.log中的登录显示大量选择,但是当尝试添加记录时,日志显示数据库永远不会被命中。

Foreman显示正在发布的数据,如下所示:

 22:38:03 web.1 | Started POST "/" for 127.0.0.1 at 2012-08-21 22:38:02 -0700 22:38:03 web.1 | Processing by MoviesController#index as HTML 22:38:03 web.1 | Parameters: {"utf8"=>"✓", "authenticity_token"=>"0AyxRbwl/Kgi05uI1KX8uxVUJjx9ylAA1ltdWgmunm4=", "movie"=>{"title"=>"Army of Darkness", "description"=>"A man fights the living dead using a boomstick.", "year"=>"1997", "genre"=>"horror"}, "commit"=>"Create Movie"} 22:38:03 web.1 | Movie Load (0.8ms) SELECT "movies".* FROM "movies" ORDER BY title 22:38:03 web.1 | Rendered movies/index.html.erb within layouts/application (14.9ms) 

失败的提交听起来像是一个很好的解释。 我还不确定如何检查驱动程序是否设置为提交或查看提交可能失败的方式/时间。

这是一个非常简单的应用程序,没有负载平衡或复杂的配置,并且大多数代码都是由’generate scaffold’命令生成的,但是完全有可能在数据库被命中之前某些约束被违反了。 也许有一种方法可以将Foreman(或Rails)日志级别提升到11? 我也尝试使用thin而不是搜索日志/文件夹中的日志文件,除了上面记录的内容之外没有找到任何其他内容。

这听起来很像交易问题,在您工作之后,您不会将事务COMMITCOMMIT ,因此更改将丢失。 如果您的SQLite驱动程序默认为COMMIT ting在没有显式COMMIT或回滚的情况下关闭的事务,并且您的Pg驱动程序默认为ROLLBACK ,那么您将获得所描述的行为。 如果SQLite默认默认自动编码每个语句,并且Pg驱动程序驱动程序默认打开一个事务,则会发生同样的情况。

这是使用相同本地数据库进行测试的众多好理由之一,因为当您要上线时,将要部署到该数据库。

如果您使用普通的Pg实例,我会告诉您在postgresql.conf启用log_statement = 'all' ,重新加载Pg,并观察日志。 你不能在Heroku上做到这一点,但你可以使用heroku logs --ps postgres访问Pg日志。 尝试运行ALTER USER my_heroku_user SET log_statement = 'all'; ,重新测试和检查日志。

或者,在本地安装Pg。

其他不太可能出现的可能性:

  • 您正在使用长时间运行的SERIALIZABLE事务进行读取,因此它们的快照永远不会更新。 不太可能。
  • 数据库对象的权限导致INSERTUPDATE等失败,您的应用程序忽略了产生的错误。 再一次,不太可能
  • 你有没有做你期望的DO INSTEAD规则,或BEFORE返回NULL触发器,因此默默地将操作转换为no-ops。 如果您使用SQLite进行测试,似乎不太可能。
  • 您正在写一个不同于您正在阅读的数据库。 在尝试从热备用群集等中读取的设置中并非不可能。