ruby-on-rails-3 - 在 Rails 3.2.16中,顺序"setval" 操作与Postgres的"nextval" 操作不一样

  显示原文与译文双语对照的内容

我有一个模型,通过 pg gem 将数据直接加载到数据库。 它通过动态创建一个CSV文件,并通过调用来将值分配给 id 字段:


self.class.select("nextval('apps_id_seq'::regclass)").first['nextval']

to_csv 实例方法中。

这在生产过程中。 但是,我正在填充某些测试,如果该测试首先运行,或者由 Database Cleaner gem 重置序列。 但它们没有给出起始值。

Postgres文档表示你可以在有问题的序列上调用 setval 来设置它。 所以假设我想将它设置为从 1开始,所以下次调用 nextval 时,它将返回 1:


select setval('apps_id_seq'::regclass, 1, false);

但是我不能与上面调用 nextval的方式相同,因为它的工作原理是无效的。 它返回零,并且不设置序列。

没有任何我尝试的迭代:


self.class.select("setval('apps_id_seq'::regclass)").first
App.connection.execute("select setval('apps_id_seq'::regclass,1,false)")
ActiveRecord::Base.connection.execute("select setval('apps_id_seq'::regclass,1)")
ActiveRecord::Base.connection.execute("select setval('apps_id_seq'::regclass,1,false)")
ActiveRecord::Base.connection.execute("select setval('apps_id_seq'::regclass,1,false)")

它的工作没有任何组合,只是 refuses 。 我不知道这是不是 pg gem 问题。

更新

这些语句在 development 模式下工作:


App.select("setval('apps_id_seq'::regclass,1)").first

还有:


App.select("nextval('apps_id_seq'::regclass)").first

然而,它们都不在 test 中工作。

但是,这些语句在 test 模式下工作:


ActiveRecord::Base.connection.execute("select setval('apps_id_seq'::regclass,1,false)").first

还有:


ActiveRecord::Base.connection.execute("select nextval('apps_id_seq'::regclass)").first

这两个环境中唯一的区别就在于我看到的是一个数据,而另一个则没有。 我的测试数据库是用 structure.sql 文件中的rake db:test:prepare 创建的。

时间: 作者:

无论表中是否包含序列的数据,setvalnextval 都将工作。 可以创建和递增序列,甚至不需要与现有表的列相关联。 使用 Model.select 执行原始数据时,ActiveRecord使用你正在使用的模型表的from子句生成 SQL 。


> App.select("setval('apps_id_seq'::regclass,1)").first

 SELECT nextval('apps_id_seq'::regclass)
 FROM"apps" ORDER BY"apps"."id" ASC LIMIT 1'

=> nil

因为在应用程序表中没有记录,所以setval函数永远不会被执行。 因为选择不具有 extraneous from子句,所以在直接使用连接时,相同选择的工作原理是相同的:


> ActiveRecord::Base.connection.execute("SELECT setval('apps_id_seq'::regclass, 1)").first

 SELECT setval('apps_id_seq'::regclass, 1)

=> {"setval"=>"1"}

使用这里窗体执行 SQL,以便确保始终对 setval 函数进行评估。

...