Python / postgres / psycopg2:挿入されたばかりの行のIDを取得


99

私はpostgresへのインターフェースにPythonとpsycopg2を使用しています。

行を挿入すると...

sql_string = "INSERT INTO hundred (name,name_slug,status) VALUES ("
sql_string += hundred_name + ", '" + hundred_slug + "', " + status + ");"
cursor.execute(sql_string)

...挿入したばかりの行のIDを取得するにはどうすればよいですか?試してみる:

hundred = cursor.fetchall() 

使用中にエラーを返しますRETURNING id

sql_string = "INSERT INTO domes_hundred (name,name_slug,status) VALUES ("
sql_string += hundred_name + ", '" + hundred_slug + "', " + status + ") RETURNING id;"
hundred = cursor.execute(sql_string)

単に戻りますNone

更新:(currvalこのコマンドをpostgresに直接使用しても機能します):

sql_string = "SELECT currval(pg_get_serial_sequence('hundred', 'id'));"
hundred_id = cursor.execute(sql_string)

誰かアドバイスできますか?

ありがとう!

回答:


206
cursor.execute("INSERT INTO .... RETURNING id")
id_of_new_row = cursor.fetchone()[0]

また、値を含むSQL文字列を手動で作成しないでください。値を個別に渡すことができるので(そうすべきです!)、エスケープする必要がなく、SQLインジェクションは不可能です。

sql_string = "INSERT INTO domes_hundred (name,name_slug,status) VALUES (%s,%s,%s) RETURNING id;"
cursor.execute(sql_string, (hundred_name, hundred_slug, status))
hundred = cursor.fetchone()[0]

詳細については、psycopgのドキュメントを参照してください:http ://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries


12
明確にするために、idin RETURNING idはシリアル/主キーフィールドのフィールド名である必要があります。
joshden 2016

9
カーソルfetchoneを使用すると、「フェッチする結果がありません」と表示されます。
Leonid

@レオニード、これを理解しましたか?
アリソンS

4
@AlisonS @Leonid同じエラーが発生RETURNING idしましたが、INSERTクエリの最後に追加すると修正されました。
Banjer

少しだけかもしれませんが、すべての人にとって重要なポイント:execute()コマンドの前に、カーソル.execute()のみを使用し、カーソル.mogrify()を使用していないことを確認してください。それ以外の場合(私の場合のように)cursor.fetchone ()は結果がありません!そのコマンドの前に「何も」なしでカーソル.execute()のみを使用すると、IDを受け取ります。
TheHeroOfTime

14

同様の問題が発生したため、ここで終了しましたが、RETURNING ID句をまだサポートしていないPostgres-XCを使用しています。その場合、以下を使用できます。

cursor.execute( 'INSERT INTO ........')
cursor.execute( 'SELECT LASTVAL()')
lastid = cursor.fetchone()['lastval']

万が一のために万が一のために!


4
覚えておいてください-それを2つのステートメントで行うと、何かがデータベースに行を直接挿入した後、lastval()コマンドがシーケンスの現在の値を返す前に、(非常に小さい)競合状態のリスクが発生します。
Dave Thomas

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.