psycopg2
では注意してください 配列に対して文字列処理を行う必要はありません。これはエラーが発生しやすく、最悪の場合、インジェクション攻撃を引き起こす可能性があるため、悪い習慣と見なされます。常にバインドされたパラメーターを使用する必要があります。以下のコードでは、タイプがTEXT[]
の列が1つだけの新しいテーブルを作成します。 (元の質問のように)。次に、新しい行を追加し、それらすべてを更新します。したがって、両方のINSERT
が表示されます およびUPDATE
操作(どちらもほとんど同じですが)
ただし、cur.execute
の1つの値のみで更新する場合は、Pythonの落とし穴が1つあります。 SQLステートメントを最初の引数および反復可能として期待します 2番目の引数としてバインドされるパラメーターを含みます。以下は 仕事:
from psycopg2 import connect
conn = connect('dbname=exhuma')
cur = conn.cursor()
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values))
conn.commit()
その理由は、(new_values)
Pythonではnew_values
と見なされます (この場合、括弧は削除されます。タプルとは見なされません)。これにより、3つの値('a'
)を指定するとエラーが発生します。 、'b'
および'c'
)バインドする値として、ただしプレースホルダーは1つだけです(%s
)クエリで。代わりに、次のように指定する必要があります(最後にコンマが追加されていることに注意してください):
from psycopg2 import connect
conn = connect('dbname=exhuma')
cur = conn.cursor()
stmt = 'UPDATE foo SET example_value=%s'
new_values = ['a', 'b', 'c']
cur.execute(stmt, (new_values,))
conn.commit()
これにより、Pythonは(new_values,)
を参照できるようになります クエリのプレースホルダーに一致する1つの要素を持つタプル(反復可能)として。末尾のコンマの詳細については、タプルに関する公式ドキュメントを参照してください。
または、[new_values]
と書くこともできます (new_values,)
の代わりに 、しかし-私の意見では-(new_values,)
タプルは不変であるのに対し、リストは可変であるため、よりクリーンです。
これが私がテストした表です:
CREATE TABLE foo (
values TEXT[]
);
そして、値の挿入と更新の両方のPythonコードは次のとおりです。
from psycopg2 import connect
conn = connect('dbname=exhuma')
cur = conn.cursor()
cur.execute('INSERT INTO foo VALUES (%s)', (['a', 'b'], ))
print('>>> Before update')
cur.execute('SELECT * FROM foo')
for row in cur:
print(type(row[0]), repr(row[0]))
print('>>> After update')
cur.execute('UPDATE foo SET example_values = %s',
(['new', 'updated', 'values'],))
cur.execute('SELECT * FROM foo')
for row in cur:
print(type(row[0]), repr(row[0]))
cur.close()
conn.commit()
conn.close()
実行のたびに、コードは同じ配列値を持つ新しい行を挿入し、WHERE
なしで更新を実行します したがって、すべての値が更新されます。数回実行した後、次の出力が得られます:
>>> Before update
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['a', 'b']")
>>> After update
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")
(<type 'list'>, "['new', 'updated', 'values']")