回答編集履歴

5

バルクインサートについて追記

2020/07/14 20:55

投稿

yymmt
yymmt

スコア1615

test CHANGED
@@ -79,3 +79,15 @@
79
79
  cur.executemany(sql, rows)
80
80
 
81
81
  ```
82
+
83
+
84
+
85
+ [追記]
86
+
87
+ どうやらpsycopg2からバルクインサートが使えるようなので参考URLを紹介。cur.executemany(sql, rows)をextras.execute_values(cur, sql, rows)にするだけで良いらしい。
88
+
89
+
90
+
91
+ - [1000万件のINSERTを映画1本分ぐらい時間節約できた話](https://datumstudio.jp/blog/postgresql%E3%81%A7insert%E9%80%9F%E5%BA%A6%E6%AF%94%E8%BC%83)
92
+
93
+ - [Postgresqlでバルクインサートする方法](https://qiita.com/K-1/items/f37654f5355f593c815f)

4

引数のミスを修正

2020/07/14 20:55

投稿

yymmt
yymmt

スコア1615

test CHANGED
@@ -76,6 +76,6 @@
76
76
 
77
77
  if len(rows) > 0:
78
78
 
79
- cur.executemany(rows)
79
+ cur.executemany(sql, rows)
80
80
 
81
81
  ```

3

Prepared Statementを追記

2020/07/14 20:40

投稿

yymmt
yymmt

スコア1615

test CHANGED
@@ -39,3 +39,43 @@
39
39
  cur.commit()
40
40
 
41
41
  ```
42
+
43
+ あるいはPrepared statementを使って
44
+
45
+ ```python
46
+
47
+ import csv
48
+
49
+ import psycopg2
50
+
51
+
52
+
53
+ sql = "INSERT INTO [テーブル] VALUES (%s, %s, %s)" # %sはカラムの数だけ書く
54
+
55
+ commit_limit = 1000 # 1000回に1回コミットする
56
+
57
+ with psycopg2.connect("****") as conn, open('[CSVファイル]', 'r') as f:
58
+
59
+ with conn.cursor() as cur:
60
+
61
+ reader = csv.reader(f)
62
+
63
+ next(reader) # ヘッダ行をスキップ
64
+
65
+ rows = []
66
+
67
+ for i, row in enumerate(reader):
68
+
69
+ rows.append(row)
70
+
71
+ if i % commit_limit == (commit_limit - 1):
72
+
73
+ cur.executemany(sql, rows)
74
+
75
+ rows = []
76
+
77
+ if len(rows) > 0:
78
+
79
+ cur.executemany(rows)
80
+
81
+ ```

2

内容を正確にした

2020/07/14 20:39

投稿

yymmt
yymmt

スコア1615

test CHANGED
@@ -1,4 +1,4 @@
1
- `\copy`はCOPYコマンドと異なり`psql`のコマンドですので、execute()で流し込むSQLとして使用することは出来ません。メモリ確保をしたくないということですので恐らく比較的ファイルサイズの大きなCSVファイルだと想像します。そのような場合、経験上INSERT文よりもCOPYコマンドのほうが(圧倒的に)高速ですので、特段の理由がない限りpsqlを使うことをお勧めします。
1
+ `\copy`はCOPYコマンドと異なり`psql`のコマンドですので、execute()で流し込むSQLとして使用することは出来ません。メモリ確保をしたくないということですので恐らく比較的ファイルサイズの大きなCSVファイルだと想像します。そのような場合、経験上INSERT文よりもCOPYコマンドのほうが(圧倒的に)高速ですので、特段の理由がない限りpsqlからCOPYコマンドを使うことをお勧めします。
2
2
 
3
3
 
4
4
 

1

typoの修正

2020/07/14 20:21

投稿

yymmt
yymmt

スコア1615

test CHANGED
@@ -1,4 +1,4 @@
1
- `\copy`はCOPYコマンドと異なり`psql`のコマンドですので、execute()で流し込むSQLとして使用することは出来ません。メモリ確保をしたくないということですので恐らく比較的ファイルサイズの大きなCSVファイルだと想像します。そのような場合、経験上INSERT文よりもCOPYコマンドのほうが(圧倒的に)高速ですので、特段の理由がない限りpsqlを使うことをお勧めします。
1
+ `\copy`はCOPYコマンドと異なり`psql`のコマンドですので、execute()で流し込むSQLとして使用することは出来ません。メモリ確保をしたくないということですので恐らく比較的ファイルサイズの大きなCSVファイルだと想像します。そのような場合、経験上INSERT文よりもCOPYコマンドのほうが(圧倒的に)高速ですので、特段の理由がない限りpsqlを使うことをお勧めします。
2
2
 
3
3
 
4
4