0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Pythonのpsycopg2でCSVファイルからNULLをインポートできない

Last updated at Posted at 2021-12-04

問題

CSVファイルからデータをインポートするときにNULLを入れようとすると怒られる。空文字列、null、NULLでも同じ。

環境

Windows10
PostgreSQL14
Python 3.10.0
psycopg2 2.9.2

テーブル作成

create table test (id varchar(10), time time);

CSVインポート

ちなみにio.StringIO(文字列)で、open関数と同じようなことがでるらしい。
公式Document:class io.StringIO

実際にCSVファイルをインポートするときはopen("/path/to/file.csv", "r")などとする。

csvimport.py
import psycopg2
import io

input = "01,12:34\n02,17:55\n03,"

with psycopg2.connect("dbname=test host=localhost user=test password=test") as conn:
    with conn.cursor() as cur:
        with io.StringIO(input) as f:
            cur.copy_from(f, table="test", sep=",")

こんな感じで登録したい。

id time
01 12:34
02 17:55
03 NULL

エラー内容

> python csvimport.py
Traceback (most recent call last):
  File "C:\***\csvimport.py", line 9, in <module>
    cur.copy_from(f, table="test", sep=",")
psycopg2.errors.InvalidDatetimeFormat: time型の入力構文が不正です: ""
CONTEXT:  testのCOPY、行 3、列 time: ""

id=03のところのtime(空文字列部分)をNULLやnullにしても同じ。

psycopg2.errors.InvalidDatetimeFormat: time型の入力構文が不正です: "NULL"
CONTEXT:  testのCOPY、行 3、列 time: "NULL"
psycopg2.errors.InvalidDatetimeFormat: time型の入力構文が不正です: "null"
CONTEXT:  testのCOPY、行 3、列 time: "null"

原因

copy_from関数でnullが、デフォルトでは\Nっていう値に設定されている。
公式Document:The cursor class

解決方法

copy_fromを呼ぶときにnull="NULL"などとして、CSVのNULLを入れたいところにNULLと書けばよい。

csvimport.py
import psycopg2
import io

input = "01,12:34\n02,17:55\n03,NULL" # NULLを入れたいところにNULLと書く

with psycopg2.connect("dbname=test host=localhost user=test password=test") as conn:
    with conn.cursor() as cur:
        with io.StringIO(input) as f:
            cur.copy_from(f, table="test", sep=",", null="NULL") # 文字列"NULL"をNULLとしてコピー

結果

修正後のcsvimport.pyを実行したらNULLを含めて登録された。

test=> select * from test;
 id |   time
----+----------
 01 | 12:34:00
 02 | 17:55:00
 03 |
(3 行)

まとめ

ドキュメントを読もう、という話ではあるんだけど、言い訳をすると、原因がどこかが分かるまではドキュメントにも行きつかないと思うんですよ。空文字とかNULLって書いたらNULLが入ると思うじゃないですか。(震え声)
環境によって何をNULLとするかは変わるっていう知見が得られた。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?