--- /dev/null
+.. change::
+ :tags: usecase, sqlite
+ :tickets: 7185
+
+ The SQLite dialect now supports UPDATE..FROM syntax, for UPDATE statements
+ that may refer to additional tables within the WHERE criteria of the
+ statement without the need to use subqueries. This syntax is invoked
+ automatically when using the :class:`_dml.Update` construct when more than
+ one table or other entity or selectable is used.
# sqlite has no "FOR UPDATE" AFAICT
return ""
+ def update_from_clause(
+ self, update_stmt, from_table, extra_froms, from_hints, **kw
+ ):
+ kw["asfrom"] = True
+ return "FROM " + ", ".join(
+ t._compiler_dispatch(self, fromhints=from_hints, **kw)
+ for t in extra_froms
+ )
+
def visit_is_distinct_from_binary(self, binary, operator, **kw):
return "%s IS NOT %s" % (
self.process(binary.left),
insert_returning = True
update_returning = True
delete_returning = True
+ update_returning_multifrom = True
default_paramstyle = "qmark"
execution_ctx_cls = SQLiteExecutionContext
def test_update_from(self, synchronize_session):
"""test an UPDATE that uses multiple tables.
- The limitation that MariaDB has with DELETE does not apply here
- at the moment as MariaDB doesn't support UPDATE..RETURNING at all.
- However, the logic from DELETE is still implemented in
- persistence.py. If MariaDB adds UPDATE...RETURNING, or SQLite adds
- UPDATE..FROM, etc., then it will be useful.
+ The limitation that MariaDB has with DELETE does not apply here at the
+ moment as MariaDB doesn't support UPDATE..RETURNING at all. However,
+ the logic from DELETE is still implemented in persistence.py. If
+ MariaDB adds UPDATE...RETURNING, then it may be useful. SQLite,
+ PostgreSQL, MSSQL all support UPDATE..FROM however RETURNING seems to
+ function correctly for all three.
"""
Engineer = self.classes.Engineer
def update_from(self):
"""Target must support UPDATE..FROM syntax"""
- return only_on(
- ["postgresql", "mssql", "mysql", "mariadb"],
+ return skip_if(
+ "oracle",
"Backend does not support UPDATE..FROM",
)