hel*_*ion 11 postgresql ruby-on-rails
升级到Rails 5后,我的架构文件在运行db:migrate时不断被更改.Rails正在发生变化:
create_table "flightlessons", force: :cascade do |t|
Run Code Online (Sandbox Code Playgroud)
至:
create_table "flightlessons", id: :integer, default: -> { "nextval('lessons_id_seq'::regclass)" }, force: :cascade do |t|
Run Code Online (Sandbox Code Playgroud)
它只发生在这一个模型上.为什么rails在这个特定型号上实现nextval?而且,为什么模型名称错误(lessons_id_seq应该是flightlessons_id_seq).但是,手动将其更改为flightlessons_id_seq会导致相同的无关系错误.
PG::UndefinedTable: ERROR: relation "lessons_id_seq" does not exist
Run Code Online (Sandbox Code Playgroud)
为了继续,我只需将schema.rb文件更改回"应该"行.然后,我可以迁移或测试:准备或者其他什么,直到下一次rails将其改回到使用nextval方法.
感谢您对此的任何见解.
Rob*_*bel 22
这有点长的答案,所以我把它分成了几个部分.系好安全带!
我的猜测是你的开发数据库确实包含了lessons_id_seq序列,并且它的定义flightlessons.id被设置为依赖于它(即,确切地说Rails放入你的模式文件中).
怎么样和为什么?你可能改名为lessons表flightlessons在过去的某个时间,但重命名并没有改变,该表依赖于序列-而且由于schema.rb它不记录序列,该lessons_id_seq序列不被复制到你的测试数据库,这样的话你得到这个错误.
要验证我的理论,请运行rails db并尝试以下命令:
\d lessons_id_seq
Run Code Online (Sandbox Code Playgroud)
这应该返回该序列的定义.然后,尝试:
\d flightlessons
Run Code Online (Sandbox Code Playgroud)
并查看id列的定义.我希望它包括在内DEFAULT nextval('lessons_id_seq').
解决此问题的最简单方法是切换到使用structure.sql而不是schema.rb(请参阅文档).这将继承数据库的确切状态,避免Rails的任何干扰或解释,这是导致您当前问题的原因.我总是推荐structure.sql用于生产系统.
但是,您也可以进入开发数据库并更改序列名称:
ALTER SEQUENCE lessons_id_seq RENAME TO flightlessons_id_seq;
ALTER TABLE flightlessons ALTER COLUMN id SET DEFAULT nextval('flightlessons_id_seq');
Run Code Online (Sandbox Code Playgroud)
这对于生产系统来说是一个糟糕的想法,但如果您的问题只是本地问题,它应该用您的问题纠正当前的数据库状态,schema.rb从而解决您当前的问题.如果您想rails db:drop db:create db:migrate使用新的应用程序,您可能希望将其编码为迁移.
Rails 5倾销default表的主键值的行为在Rails 5中可能是新的.以前,Rails可能只是相信你的ID列有一个合理的默认值,并忽略它实际看到的任何值.但我还没有做过研究,看看这是不是真的.
| 归档时间: |
|
| 查看次数: |
1431 次 |
| 最近记录: |