ORMなしでSQLAlchemyを使用しています。つまり、手作りのSQLstatememtsを使用してバックエンドデータベースと直接対話しています。この場合、バックエンドデータベースとしてPGを使用しています(DBドライバーとしてpsycopg2)-それが答えに影響するかどうかはわかりません。
私はこのようなステートメントを持っています(簡潔にするために、connがdbへの有効な接続であると仮定します):
conn.execute("INSERT INTO user (name, country_id) VALUES ('Homer', 123)")
また、ユーザーテーブルが列(id [SERIAL PRIMARY KEY]、name、country_id)で構成されていると仮定します。
新しいユーザーのIDを取得するにはどうすればよいですか(理想的には、dbを再度押すことなく)。
RETURNING
ステートメント のINSERT
句を次のように使用できる場合があります。
result = conn.execute("INSERT INTO user (name, country_id) VALUES ('Homer', 123)
RETURNING *")
結果のid
のみが必要な場合:
rslt_id = conn.execute("INSERT INTO user (name, country_id) VALUES ('Homer', 123)
RETURNING id")
ユーザー lastrowid
result = conn.execute("INSERT INTO user (name, country_id) VALUES ('Homer', 123)")
result.lastrowid
現在のSQLAlchemy ドキュメント 提案
result.inserted_primary_key
動作するはずです!
この質問はstackoverflowで何度も聞かれましたが、私が見た答えは包括的ではありません。グーグル 'sqlalchemy insert get id of new row'は、それらの多くを表示します。
SQLAlchemyには3つのレベルがあります。上:ORM。中央:テーブルクラスなどを使用したデータベース抽象化(DBA)。下:テキスト関数を使用したSQL。
OOプログラマーにとってはORMレベルは自然に見えますが、データベースプログラマーにとっては見苦しく、ORMが邪魔になります。DBAレイヤーは妥協点として問題ありません。SQLレイヤーはデータベースにとって自然に見えます。プログラマーであり、オブジェクト指向のみのプログラマーには異質に見えます。
各レベルには独自の構文があり、似ていますが、イライラするほど異なっています。これに加えて、オンラインのドキュメントが多すぎて、答えを見つけるのが非常に困難です。
挿入されたIDを取得する方法を説明しますAT使用するRDBMSのSQLレイヤー。
Table: User(user_id integer primary autoincrement key, user_name string)
conn: Is a Connection obtained within SQLAlchemy to the DBMS you are using.
SQLite
======
insstmt = text(
'''INSERT INTO user (user_name)
VALUES (:usernm) ''' )
# Execute within a transaction (optional)
txn = conn.begin()
result = conn.execute(insstmt, usernm='Jane Doe')
# The id!
recid = result.lastrowid
txn.commit()
MS SQL Server
=============
insstmt = text(
'''INSERT INTO user (user_name)
OUTPUT inserted.record_id
VALUES (:usernm) ''' )
txn = conn.begin()
result = conn.execute(insstmt, usernm='Jane Doe')
# The id!
recid = result.fetchone()[0]
txn.commit()
MariaDB/MySQL
=============
insstmt = text(
'''INSERT INTO user (user_name)
VALUES (:usernm) ''' )
txn = conn.begin()
result = conn.execute(insstmt, usernm='Jane Doe')
# The id!
recid = conn.execute(text('SELECT LAST_INSERT_ID()')).fetchone()[0]
txn.commit()
Postgres
========
insstmt = text(
'''INSERT INTO user (user_name)
VALUES (:usernm)
RETURNING user_id ''' )
txn = conn.begin()
result = conn.execute(insstmt, usernm='Jane Doe')
# The id!
recid = result.fetchone()[0]
txn.commit()
result.inserted_primary_key
私のために働いた。注意すべき唯一のことは、これがそのlast_insert_idを含むリストを返すことです。
returning
オブジェクトを受け取るには必ずfetchrow/fetch
を使用してください
insert_stmt = user.insert().values(name="homer", country_id="123").returning(user.c.id)
row_id = await conn.fetchrow(insert_stmt)