postgresql nextval生成现有值

我不得不从rails app上的基于mySql的ruby迁移到使用postgresql。 到目前为止没有问题,我不知道如何解决它。

数据的迁移带来了id,而postgresql现在遇到了现有id的问题:我不清楚它在哪里获得用于确定nextval基数的值:它肯定不是最高值专栏,虽然您可能认为这是一个好主意。 无论如何,它现在与现有的id值冲突。 从标准RoR迁移创建的id列定义为

not null default nextval('geopoints_id_seq'::regclass) 

是否有一些地方可以将其作为基础使用的价值入侵? 这个问题现在可能出现在20个左右的表中:我可以使用

 'select max(id) from '

但这似乎使自动增量柱的想法毫无意义。

如何最好地处理?

有一个reset_pk_sequences! Postgres适配器上的方法。 你可以调用它,它会将它设置为max(id)+ 1,这可能是你想要的。

在某些项目中,我经常获得ETL数据,以保证所有模型或指定模型执行此操作的rake任务。 这是任务 – 将它包含在一些Rakefile中或者它自己的lib / tasks下:

 desc "Reset all sequences. Run after data imports" task :reset_sequences, :model_class, :needs => :environment do |t, args| if args[:model_class] classes = Array(eval args[:model_class]) else puts "using all defined active_record models" classes = [] Dir.glob(RAILS_ROOT + '/app/models/**/*.rb').each { |file| require file } Object.subclasses_of(ActiveRecord::Base).select { |c| c.base_class == c}.sort_by(&:name).each do |klass| classes << klass end end classes.each do |klass| next if klass == CGI::Session::ActiveRecordStore::Session && ActionController::Base.session_store.to_s !~ /ActiveRecordStore/ puts "reseting sequence on #{klass.table_name}" ActiveRecord::Base.connection.reset_pk_sequence!(klass.table_name) end end 

现在,您可以使用rake reset_sequences为所有模型(在RAIS_ROOT / app / models下定义)运行此项,或者通过传入类名称为特定模型运行此项。

rails 3版本看起来像这样:

 namespace :db do desc "Reset all sequences. Run after data imports" task :reset_sequences, :model_class, :needs => :environment do |t, args| if args[:model_class] classes = Array(eval args[:model_class]) else puts "using all defined active_record models" classes = [] Dir.glob(RAILS_ROOT + '/app/models/**/*.rb').each { |file| require file } ActiveRecord::Base.subclasses.select { |c|c.base_class == c}.sort_by(&:name).each do |klass| classes << klass end end classes.each do |klass| puts "reseting sequence on #{klass.table_name}" ActiveRecord::Base.connection.reset_pk_sequence!(klass.table_name) end end end 

https://gist.github.com/909032

使用该定义,该列将从geopoints_id_seq序列中获取下一个值。 该序列不直接附加到表中。 如果要迁移数据,则必须创建或更新该序列,使其起点大于表中的当前最大ID。

您应该能够使用例如设置其新值

  ALTER SEQUENCE geopoints_id_seq RESTART with 1692; 

或者从table_name中选择max(id); 产量

PG使用序列:

使它的当前值1高于表中的最高值,如下所示。

 SELECT setval('geopoints_id_seq', 999999999, true); 

另见这些

http://www.postgresql.org/docs/8.4/interactive/datatype-numeric.html#DATATYPE-SERIAL

http://www.postgresql.org/docs/8.4/interactive/functions-sequence.html

使用setval()设置序列的起始值。

Interesting Posts