web-dev-qa-db-ja.com

挿入Python Psycopg2を使用した辞書

すべてのキーを列挙せずにPostgresデータベースに多くのキーを持つpython辞書を挿入する最良の方法は何ですか?

次のようなことをしたい...

song = dict()
song['title'] = 'song 1'
song['artist'] = 'artist 1'
...

cursor.execute('INSERT INTO song_table (song.keys()) VALUES (song)')
24
user3783608
from psycopg2.extensions import AsIs

song = {
    'title': 'song 1',
    'artist': 'artist 1'
}

columns = song.keys()
values = [song[column] for column in columns]

insert_statement = 'insert into song_table (%s) values %s'

    # cursor.execute(insert_statement, (AsIs(','.join(columns)), Tuple(values)))
print cursor.mogrify(insert_statement, (AsIs(','.join(columns)), Tuple(values)))

プリント:

insert into song_table (artist,title) values ('artist 1', 'song 1')

PsycopgはTuplerecordに適合させ、 AsIs はPythonの文字列置換によって行われることを行います。

25
Clodoaldo Neto

dictionaryを使用して複数の行を挿入することもできます。次のものがある場合:

namedict = ({"first_name":"Joshua", "last_name":"Drake"},
            {"first_name":"Steven", "last_name":"Foo"},
            {"first_name":"David", "last_name":"Bar"})

次を使用して、辞書内に3行すべてを挿入できます。

cur = conn.cursor()
cur.executemany("""INSERT INTO bar(first_name,last_name) VALUES (%(first_name)s, %(last_name)s)""", namedict)

cur.executemanyステートメントは、辞書を自動的に反復処理し、各行に対してINSERTクエリを実行します。

PS:この例は here から取られています

17
vikas

これらの行に沿って何かを行う必要があります:

song = dict()
song['title'] = 'song 1'
song['artist'] = 'artist 1'

cols=song.keys();

vals = [song[x] for x in cols]
vals_str_list = ["%s"] * len(vals)
vals_str = ", ".join(vals_str_list)

cursor.execute("INSERT INTO song_table ({cols}) VALUES ({vals_str})".format(
               cols = cols, vals_str = vals_str), vals)

キー部分は%s要素の生成された文字列であり、formatでそれを使用し、リストがexecute呼び出しに直接渡されるため、psycopg2 = valsリスト内の各アイテムを補間できます(したがって、可能性のある防止SQLインジェクション)。

dictexecuteに渡す別のバリエーションは、上記のvalsvals_str_listおよびvals_strの代わりにこれらの行を使用することです。

vals_str2 = ", ".join(["%({0})s".format(x) for x in cols])

cursor.execute("INSERT INTO song_table ({cols}) VALUES ({vals_str})".format(
               cols = cols, vals_str = vals_str2), song)
11
khampson

この目的のために新しいsqlモジュールが作成され、psycopg2バージョン2.7で追加されました。ドキュメントによると:

SQLクエリを動的に生成する必要がある場合(たとえば、テーブル名を動的に選択する場合)、psycopg2.sqlモジュールで提供される機能を使用できます。

ドキュメントには2つの例が示されています。 http://initd.org/psycopg/docs/sql.html

names = ['foo', 'bar', 'baz']

q1 = sql.SQL("insert into table ({}) values ({})").format(
    sql.SQL(', ').join(map(sql.Identifier, names)),
    sql.SQL(', ').join(sql.Placeholder() * len(names)))
print(q1.as_string(conn))

テーブル( "foo"、 "bar"、 "baz")の値(%s、%s、%s)に挿入します

q2 = sql.SQL("insert into table ({}) values ({})").format(
    sql.SQL(', ').join(map(sql.Identifier, names)),
    sql.SQL(', ').join(map(sql.Placeholder, names)))
print(q2.as_string(conn))

テーブルへの挿入( "foo"、 "bar"、 "baz")値(%(foo)s、%(bar)s、%(baz)s)

文字列の連結は同じ結果を生成しますが、psycopg2のドキュメントによると、この目的には使用しないでください。

警告:しない、never[〜#〜] never [〜#〜]use Python string concatenation(+)または文字列パラメーターの補間(%)変数をSQLクエリ文字列に渡します。銃口でもない。

4