大量插入轨道模型,如何自动增加id字段?

时间:2013-03-14 21:32:00

标签: ruby-on-rails

我有一个股票模型和stock_price_history模型。

我想用这个

进行大量插入
sqlstatement = "INSERT INTO stock_histories SELECT datapoint1 AS id, 
datapoint2 AS `date` ...UNION SELECT datapoint9,10,11,12,13,14,15,16, 
UNION SELECT datapoint 17... etc"

ActiveRecord::Base.connection.execute sqlstatement

但是,我实际上并不想使用datapoint1 AS id。如果我把它留空,我得到一个错误,我的模型有10个字段,我只插入9并且它缺少主键。

有没有办法在通过SQL插入时强制在id上自动增加?

编辑:奖金问题因为我是菜鸟。我正在使用SQLite3开发并部署到Posgres(即Heroku),我是否需要修改上面的大量插入语句,以便它适用于posgres数据库?

第二次编辑:我的初始问题有Assets和AssetHistory而不是Stocks和Stock_Histories。我将其更改为股票/股票价格历史,因为我认为它更直观易懂。因此,由于这个原因,一些答案参考资产历史。

1 个答案:

答案 0 :(得分:1)

您可以更改SQL并更明确地了解要插入的字段,并将id从列表中删除:

insert into asset_histories (date) select datapoint2 as `date` ...etc

这是一个很长的真实例子:

jim=# create table test1 (id serial not null, date date not null, name text not null);
NOTICE:  CREATE TABLE will create implicit sequence "test1_id_seq" for serial column "test1.id"
CREATE TABLE
jim=# create table test2 (id serial not null, date date not null, name text not null);
NOTICE:  CREATE TABLE will create implicit sequence "test2_id_seq" for serial column "test2.id"
CREATE TABLE
jim=# insert into test1 (date, name) values (now(), 'jim');
INSERT 0 1
jim=# insert into test1 (date, name) values (now(), 'joe');
INSERT 0 1
jim=# insert into test1 (date, name) values (now(), 'bob');
INSERT 0 1
jim=# select * from test1;
 id |    date    | name
----+------------+------
  1 | 2013-03-14 | jim
  2 | 2013-03-14 | joe
  3 | 2013-03-14 | bob
(3 rows)
jim=# insert into test2 (date, name) select date, name from test1 where name <> 'jim';
INSERT 0 2
jim=# select * from test2;
 id |    date    | name
----+------------+------
  1 | 2013-03-14 | joe
  2 | 2013-03-14 | bob
(2 rows)

如您所见,仅插入了选定的行,并在表id中为它们分配了新的test2值。您必须明确要插入的所有字段,并确保插入的顺序和选择匹配。

说了这么多,你可能想看看activerecord-import宝石,这使得这类东西更加Railsy。假设您有一堆新的AssetHistory对象(尚未保留),您可以将它们全部插入:

asset_histories = []
asset_histories << AssetHistory.new date: some_date
asset_histories << AssetHistory.new date: some_other_date
AssetHistory.import asset_histories

这将在表格中生成一个有效的插入,并为您处理id。您仍然需要查询一些数据并构造对象,这可能不会比使用原始SQL更快地完成,但如果您已经在Ruby对象中获取了数据,则可能是更好的选择。