您可以更改您的 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 对象中获得了数据,这可能是一个更好的选择。