\copy
はCOPYコマンドと異なりpsql
のコマンドですので、execute()で流し込むSQLとして使用することは出来ません。メモリ確保をしたくないということですので恐らく比較的ファイルサイズの大きなCSVファイルだと想像します。そのような場合、経験上INSERT文よりもCOPYコマンドのほうが(圧倒的に)高速ですので、特段の理由がない限りpsqlからCOPYコマンドを使うことをお勧めします。
遅くても構わないのでPythonで行いたいということであれば(copy_fromを使わない方法としては)、INSERT文を組み立てることになります。一行ずつだと遅いのでcommitはある程度まとまってからcommitするほうが良いです。
python
1import csv
2import psycopg2
3
4sql = "INSERT INTO [テーブル] VALUES (%s, %s, %s)" # %sはカラムの数だけ書く
5commit_limit = 1000 # 1000回に1回コミットする
6with psycopg2.connect("****") as conn, open('[CSVファイル]', 'r') as f:
7 conn.autocommit = False
8 with conn.cursor() as cur:
9 reader = csv.reader(f)
10 next(reader) # ヘッダ行をスキップ
11 for i, row in enumerate(reader):
12 cur.execute(sql, row)
13 if i % commit_limit == (commit_limit - 1):
14 cur.commit()
15 cur.commit()
あるいはPrepared statementを使って
python
1import csv
2import psycopg2
3
4sql = "INSERT INTO [テーブル] VALUES (%s, %s, %s)" # %sはカラムの数だけ書く
5commit_limit = 1000 # 1000回に1回コミットする
6with psycopg2.connect("****") as conn, open('[CSVファイル]', 'r') as f:
7 with conn.cursor() as cur:
8 reader = csv.reader(f)
9 next(reader) # ヘッダ行をスキップ
10 rows = []
11 for i, row in enumerate(reader):
12 rows.append(row)
13 if i % commit_limit == (commit_limit - 1):
14 cur.executemany(sql, rows)
15 rows = []
16 if len(rows) > 0:
17 cur.executemany(sql, rows)
[追記]
どうやらpsycopg2からバルクインサートが使えるようなので参考URLを紹介。cur.executemany(sql, rows)をextras.execute_values(cur, sql, rows)にするだけで良いらしい。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/15 05:38