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データベース用に変更する必要がありますか?

2番目の編集:私の最初の質問には、StocksとStock_HistoriesではなくAssetsとAssetHistoryがありました。わかりやすいと思ったので、株価・株価履歴に変更しました。したがって、一部の回答は、この理由で資産履歴を参照しています。

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テーブルに新しい値が割り当てられました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

これにより、テーブルへの効率的な挿入が1つ生成され、が自動的に処理idされます。それでも、いくつかのデータをクエリしてオブジェクトを作成する必要があります。これは、生のSQLですべてを実行するよりも高速ではない場合がありますが、Rubyオブジェクトにデータが既にある場合はより良い代替手段になる可能性があります。

于 2013-03-14T21:44:35.800 に答える