0

我有一个股票模型和一个 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。我将其更改为股票/股票价格历史,因为我认为它更易于理解。因此,出于这个原因,一些答案会参考资产历史。

4

1 回答 1

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在 table 中为它们分配了新值test2。您必须明确要插入的所有字段,并确保插入的顺序和选择匹配。

说了这么多,您可能想研究一下activerecord-import gem,这使得这类事情更像 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 对象中获得了数据,这可能是一个更好的选择。

于 2013-03-14T21:44:35.800 回答