我有一个迁移,它创建一个自动递增主标识符的postres序列,然后执行一个声明来更改列并指定默认值:
execute 'CREATE SEQUENCE "ServiceAvailability_ID_seq";'
execute <<-SQL
ALTER TABLE "ServiceAvailability"
ALTER COLUMN "ID" set DEFAULT NEXTVAL('ServiceAvailability_ID_seq');
SQL
如果我运行db:migrate,一切似乎都有效,因为没有返回错误,但是,如果我运行rails应用程序,我得到:
列“ID”中的Mnull值违反非空约束
我通过在迁移中手动执行sql语句发现,这个错误是因为alter语句不起作用,或者没有被执行。
如果我手动执行以下语句:
CREATE SEQUENCE "ServiceAvailability_ID_seq;
我明白了:
错误:错误:关系“serviceavailability_id_seq”已存在
这意味着迁移成功创建了序列!但是,如果我手动运行:
ALTER TABLE "ServiceProvider"
ALTER COLUMN "ID" set DEFAULT NEXTVAL('ServiceProvider_ID_seq');
SQL
它成功运行并创建默认的NEXTVAL。
所以问题是,为什么迁移文件使用第一个执行语句创建序列,而不是在第二个执行中更改表? (记住,运行db:migrate时不会输出错误)
感谢并为tl:dr
道歉答案 0 :(得分:0)
我将序列的创建和表的更改分成两个迁移。
运行时:
rake db:migrate
不会创建序列,也不会更改表格,并且rake会成功运行。
但是,如果我单独进行迁移:
rake db:migrate VERSION=1
rake db:migrate VERSION=2
将创建序列,并按预期更改表格。