Skip to content

Commit f1a338f

Browse files
Taliikamotl
authored andcommitted
Enable RETURNING clause for sqlalchemy 2.0
1 parent f5e1072 commit f1a338f

2 files changed

Lines changed: 71 additions & 0 deletions

File tree

docs/by-example/sqlalchemy/advanced-querying.rst

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,73 @@ Now, verify that the data is present in the database:
257257
["('Write Tests',)"]
258258

259259

260+
``INSERT...RETURNING``
261+
======================
262+
263+
The ``RETURNING`` clause can be used to retrieve the result rows of an ``INSERT``
264+
operation. It may be specified using the ``Insert.returning()`` method.
265+
266+
The first step is to define the table:
267+
268+
>>> from sqlalchemy import insert
269+
270+
>>> class User(Base):
271+
... __tablename__ = 'user'
272+
... __table_args__ = {
273+
... 'crate_number_of_replicas': '0'
274+
... }
275+
... id = sa.Column(sa.String, primary_key=True, default=gen_key)
276+
... username = sa.Column(sa.String)
277+
... email = sa.Column(sa.String)
278+
279+
>>> Base.metadata.create_all(bind=engine)
280+
281+
Now, let's use the returning clause on our insert to retrieve the values inserted:
282+
283+
>>> ins = insert(User).values(username='Crate', email='crate@crate.io').returning(User.username, User.email)
284+
>>> result = session.execute(ins)
285+
>>> session.commit()
286+
>>> print([str(r) for r in result])
287+
["('Crate', 'crate@crate.io')"]
288+
289+
The following ``INSERT...RETURNING`` statement was issued to the database:
290+
291+
INSERT INTO user (id, username, email)
292+
VALUES (:id, :username, :email)
293+
RETURNING user.id, user.username, user.email
294+
295+
``UPDATE...RETURNING``
296+
297+
The ``RETURNING`` clause can also be used with an ``UPDATE`` operation to return
298+
specified rows to be returned on execution. It can be specified using the
299+
``Update.returning()`` method.
300+
301+
302+
We can reuse the user table previously created in the ``INSERT...RETURNING`` section.
303+
304+
Insert a user and get the user id:
305+
306+
>>> from sqlalchemy import insert, update
307+
308+
>>> ins = insert(User).values(username='Arthur Dent', email='arthur_dent@crate.io').returning(User.id, User.username, User.email)
309+
>>> result = session.execute(ins)
310+
>>> session.commit()
311+
>>> uid = [r[0] for r in result][0]
312+
313+
Now let's update the user:
314+
315+
>>> updt = update(User).where(User.id == uid).values(username='Tricia McMillan', email='tricia_mcmillan@crate.io').returning(User.username, User.email)
316+
>>> res = session.execute(updt)
317+
>>> session.commit()
318+
>>> print([str(r) for r in res])
319+
["('Tricia McMillan', 'tricia_mcmillan@crate.io')"]
320+
321+
The following ``UPDATE...RETURNING`` statement was issued to the database:
322+
323+
UPDATE user SET username=:username, email=:email
324+
WHERE user.id = :id_1
325+
RETURNING user.username, user.email
326+
260327
.. hidden: Disconnect from database
261328
262329
>>> session.close()
@@ -265,3 +332,5 @@ Now, verify that the data is present in the database:
265332
266333
267334
.. _count result rows: https://docs.sqlalchemy.org/en/14/orm/tutorial.html#counting
335+
336+
UPDATE stuff SET content=:content WHERE stuff.id = :id_1 RETURNING stuff.content, stuff.status

src/crate/client/sqlalchemy/dialect.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ class CrateDialect(default.DefaultDialect):
180180
supports_statement_cache = True
181181
colspecs = colspecs
182182
implicit_returning = True
183+
insert_returning = True
184+
update_returning = True
183185

184186
def __init__(self, *args, **kwargs):
185187
super(CrateDialect, self).__init__(*args, **kwargs)

0 commit comments

Comments
 (0)