I have a model that loads data directly to the database with the pg
gem. It does this by creating a CSV file on the fly, and assigning the values to the id
field by calling:
self.class.select("nextval('apps_id_seq'::regclass)").first['nextval']
in a to_csv
instance method.
This works great in production. However, I'm in the process of
filling in some tests, and if this test is run first, or by itself, it
fails because the DB has just been reset by the Database Cleaner
gem and the sequences are reset. But they aren't given a starting value.
Postgres documentation says you can call setval
on the sequence in question to set it up. So let's say I want to set it up to start at 1, so that the next time nextval
is called, it will return a 1:
select setval('apps_id_seq'::regclass, 1, false);
But I can't call this the same way as I call nextval
above, because it just plain doesn't work. It returns nil, and does not set up the sequence.
No iteration of anything I try:
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)")
nor any combination thereof works, it just refuses
to work. I don't know if it's a pg
gem problem.
These statements work in development
mode:
App.select("setval('apps_id_seq'::regclass,1)").first
and:
App.select("nextval('apps_id_seq'::regclass)").first
Yet, neither of them work in test
.
BUT, these statements DO work in test
mode:
ActiveRecord::Base.connection.execute("select setval('apps_id_seq'::regclass,1,false)").first
and:
ActiveRecord::Base.connection.execute("select nextval('apps_id_seq'::regclass)").first
The ONLY DIFFERENCE in the two environments, as far as I can see, is
that one has data, while the other one does not. And my test db is
created with rake db:test:prepare
from a structure.sql
file.
I have determined that setval and nextval WILL NOT WORK AS ADVERTISED UNLESS DATA IS PRESENT IN THE UNDERLYING TABLE.
I proved this by using AR create on the model to create a dummy record. Then, the commands worked fine.
I then deleted the dummy record, tried the commands again, and failed again.