diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-11-11 10:42:09 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-11-11 10:42:09 -0500 |
| commit | afb26d79d7b9256ee26b4d3b8550f7088f4b6249 (patch) | |
| tree | 6a8aa0f31609fa13f1c91bbf1fab4f6666df6745 /doc/build | |
| parent | 585e38cd4317f41d1cf1fa384b094b64f72fe0f8 (diff) | |
| download | sqlalchemy-afb26d79d7b9256ee26b4d3b8550f7088f4b6249.tar.gz | |
Remove misleading correlation examples
add links to tutorial docs
Fixes: #5694
Change-Id: I10a8e3f46a115945ded36d4ee59165c056c10f7a
Diffstat (limited to 'doc/build')
| -rw-r--r-- | doc/build/core/tutorial.rst | 1 | ||||
| -rw-r--r-- | doc/build/tutorial/data.rst | 181 |
2 files changed, 100 insertions, 82 deletions
diff --git a/doc/build/core/tutorial.rst b/doc/build/core/tutorial.rst index 1248e00a3..e927a77ce 100644 --- a/doc/build/core/tutorial.rst +++ b/doc/build/core/tutorial.rst @@ -2390,6 +2390,7 @@ used to achieve this: COMMIT {stop}<sqlalchemy.engine.cursor.LegacyCursorResult object at 0x...> +.. _tutorial_1x_correlated_updates: Correlated Updates ------------------ diff --git a/doc/build/tutorial/data.rst b/doc/build/tutorial/data.rst index 6238e5e1f..27a21b097 100644 --- a/doc/build/tutorial/data.rst +++ b/doc/build/tutorial/data.rst @@ -1212,6 +1212,8 @@ from a Core-centric perspective. use are discussed in the sections :ref:`tutorial_orm_updating` and :ref:`tutorial_orm_deleting`. +.. _tutorial_core_update: + The update() SQL Expression Construct ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1279,85 +1281,93 @@ that literal values would normally go: <sqlalchemy.engine.cursor.CursorResult object at 0x...> COMMIT{stop} -Other techniques which may be applied to UPDATE include: - -* **Correlated Updates**: a :ref:`correlated subquery <tutorial_scalar_subquery>` - may be used anywhere a column expression might be - placed:: - - >>> scalar_subq = ( - ... select(address_table.c.email_address). - ... where(address_table.c.user_id == user_table.c.id). - ... order_by(address_table.c.id). - ... limit(1). - ... scalar_subquery() - ... ) - >>> update_stmt = update(user_table).values(fullname=scalar_subq) - >>> print(update_stmt) - {opensql}UPDATE user_account SET fullname=(SELECT address.email_address - FROM address - WHERE address.user_id = user_account.id ORDER BY address.id - LIMIT :param_1) - - .. - - -* **UPDATE..FROM**: Some databases such as PostgreSQL and MySQL support a syntax - "UPDATE FROM" where additional tables may be stated in the FROM clause. - This syntax will be generated implicitly when additional tables are located - in the WHERE clause of the statement:: - - >>> update_stmt = ( - ... update(user_table). - ... where(user_table.c.id == address_table.c.user_id). - ... where(address_table.c.email_address == 'patrick@aol.com'). - ... values(fullname='Pat') - ... ) - >>> print(update_stmt) - {opensql}UPDATE user_account SET fullname=:fullname FROM address - WHERE user_account.id = address.user_id AND address.email_address = :email_address_1 - - .. -* **UPDATE..FROM updating multiple tables**: this is a MySQL specific syntax which - requires we refer to :class:`_schema.Table` objects in the VALUES - clause in order to refer to additional tables:: +Other techniques which may be applied to UPDATE include: - >>> update_stmt = ( - ... update(user_table). - ... where(user_table.c.id == address_table.c.user_id). - ... where(address_table.c.email_address == 'patrick@aol.com'). - ... values( - ... { - ... user_table.c.fullname: "Pat", - ... address_table.c.email_address: "pat@aol.com" - ... } - ... ) - ... ) - >>> from sqlalchemy.dialects import mysql - >>> print(update_stmt.compile(dialect=mysql.dialect())) - {opensql}UPDATE user_account, address - SET address.email_address=%s, user_account.fullname=%s - WHERE user_account.id = address.user_id AND address.email_address = %s +.. _tutorial_correlated_updates: - .. +Correlated Updates +~~~~~~~~~~~~~~~~~~ -* **Parameter Ordered Updates**: Another MySQL-only behavior is that the order - of parameters in the SET clause of an UPDATE actually impacts the evaluation - of each expression. For this use case, the :meth:`_sql.Update.ordered_values` - method accepts a sequence of tuples so that this order may be controlled [1]_:: +An UPDATE statement can make use of rows in other tables by using a +:ref:`correlated subquery <tutorial_scalar_subquery>`. A subuqery may be used +anywhere a column expression might be placed:: + + >>> scalar_subq = ( + ... select(address_table.c.email_address). + ... where(address_table.c.user_id == user_table.c.id). + ... order_by(address_table.c.id). + ... limit(1). + ... scalar_subquery() + ... ) + >>> update_stmt = update(user_table).values(fullname=scalar_subq) + >>> print(update_stmt) + {opensql}UPDATE user_account SET fullname=(SELECT address.email_address + FROM address + WHERE address.user_id = user_account.id ORDER BY address.id + LIMIT :param_1) + + +.. _tutorial_update_from: + +UPDATE..FROM +~~~~~~~~~~~~~ + +Some databases such as PostgreSQL and MySQL support a syntax "UPDATE FROM" +where additional tables may be stated directly in a special FROM clause. This +syntax will be generated implicitly when additional tables are located in the +WHERE clause of the statement:: + + >>> update_stmt = ( + ... update(user_table). + ... where(user_table.c.id == address_table.c.user_id). + ... where(address_table.c.email_address == 'patrick@aol.com'). + ... values(fullname='Pat') + ... ) + >>> print(update_stmt) + {opensql}UPDATE user_account SET fullname=:fullname FROM address + WHERE user_account.id = address.user_id AND address.email_address = :email_address_1 + + +There is also a MySQL specific syntax that can UPDATE multiple tables. This +requires we refer to :class:`_schema.Table` objects in the VALUES clause in +order to refer to additional tables:: + + >>> update_stmt = ( + ... update(user_table). + ... where(user_table.c.id == address_table.c.user_id). + ... where(address_table.c.email_address == 'patrick@aol.com'). + ... values( + ... { + ... user_table.c.fullname: "Pat", + ... address_table.c.email_address: "pat@aol.com" + ... } + ... ) + ... ) + >>> from sqlalchemy.dialects import mysql + >>> print(update_stmt.compile(dialect=mysql.dialect())) + {opensql}UPDATE user_account, address + SET address.email_address=%s, user_account.fullname=%s + WHERE user_account.id = address.user_id AND address.email_address = %s + + +Parameter Ordered Updates +~~~~~~~~~~~~~~~~~~~~~~~~~~ - >>> update_stmt = ( - ... update(some_table). - ... ordered_values( - ... (some_table.c.y, 20), - ... (some_table.c.x, some_table.c.y + 10) - ... ) - ... ) - >>> print(update_stmt) - {opensql}UPDATE some_table SET y=:y, x=(some_table.y + :y_1) +Another MySQL-only behavior is that the order of parameters in the SET clause +of an UPDATE actually impacts the evaluation of each expression. For this use +case, the :meth:`_sql.Update.ordered_values` method accepts a sequence of +tuples so that this order may be controlled [1]_:: - .. + >>> update_stmt = ( + ... update(some_table). + ... ordered_values( + ... (some_table.c.y, 20), + ... (some_table.c.x, some_table.c.y + 10) + ... ) + ... ) + >>> print(update_stmt) + {opensql}UPDATE some_table SET y=:y, x=(some_table.y + :y_1) .. [1] While Python dictionaries are `guaranteed to be insert ordered @@ -1367,6 +1377,7 @@ Other techniques which may be applied to UPDATE include: measure of clarity of intent when it is essential that the SET clause of a MySQL UPDATE statement proceed in a specific way. +.. _tutorial_deletes: The delete() SQL Expression Construct ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -1388,19 +1399,25 @@ allowing for a RETURNING variant. >>> print(stmt) {opensql}DELETE FROM user_account WHERE user_account.name = :name_1 + +.. _tutorial_multi_table_deletes: + +Multiple Table Deletes +~~~~~~~~~~~~~~~~~~~~~~ + Like :class:`_sql.Update`, :class:`_sql.Delete` supports the use of correlated subqueries in the WHERE clause as well as backend-specific multiple table syntaxes, such as ``DELETE FROM..USING`` on MySQL:: - >>> delete_stmt = ( - ... delete(user_table). - ... where(user_table.c.id == address_table.c.user_id). - ... where(address_table.c.email_address == 'patrick@aol.com') - ... ) - >>> from sqlalchemy.dialects import mysql - >>> print(delete_stmt.compile(dialect=mysql.dialect())) - {opensql}DELETE FROM user_account USING user_account, address - WHERE user_account.id = address.user_id AND address.email_address = %s + >>> delete_stmt = ( + ... delete(user_table). + ... where(user_table.c.id == address_table.c.user_id). + ... where(address_table.c.email_address == 'patrick@aol.com') + ... ) + >>> from sqlalchemy.dialects import mysql + >>> print(delete_stmt.compile(dialect=mysql.dialect())) + {opensql}DELETE FROM user_account USING user_account, address + WHERE user_account.id = address.user_id AND address.email_address = %s Getting Affected Row Count from UPDATE, DELETE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
