Skip to content

Commit 72268e9

Browse files
committed
tutorial updates re: Core /ORM commonality
updates for Insert / bulk insert, executemanyvalues, as well as beginning to describe Table / declared class more closely together, mentioning typing support. Fixed a long-standing issue where sphinx would complain about the Insert symbol being ambiguous. Change-Id: Id4cc09b9581e8fa39c9c00bc8f229636e626e9bc
1 parent 124edd2 commit 72268e9

4 files changed

Lines changed: 37 additions & 35 deletions

File tree

doc/build/tutorial/data_insert.rst

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,27 @@
1111

1212
.. _tutorial_core_insert:
1313

14-
Inserting Rows with Core
15-
-------------------------
14+
Inserting Rows with ``Insert()`` Constructs
15+
-------------------------------------------
1616

17-
When using Core, a SQL INSERT statement is generated using the
18-
:func:`_sql.insert` function - this function generates a new instance of
19-
:class:`_sql.Insert` which represents an INSERT statement in SQL, that adds
20-
new data into a table.
17+
When using Core as well as within some ORM use cases, a SQL INSERT statement is
18+
generated directly using the :func:`_sql.insert` function - this function
19+
generates a new instance of :class:`_sql.Insert` which represents an INSERT
20+
statement in SQL, that adds new data into a table.
2121

2222
.. container:: orm-header
2323

24-
**ORM Readers** - The way that rows are INSERTed into the database from an ORM
25-
perspective makes use of object-centric APIs on the :class:`_orm.Session` object known as the
26-
:term:`unit of work` process,
27-
and is fairly different from the Core-only approach described here.
28-
The more ORM-focused sections later starting at :ref:`tutorial_inserting_orm`
29-
subsequent to the Expression Language sections introduce this.
24+
**ORM Readers** -
25+
26+
The ORM's means of generating INSERT statements is described in
27+
one of two ways; the most common is by using
28+
the :term:`unit of work` process which automates the generation of
29+
INSERT statements from object state, and is introduced
30+
at :ref:`tutorial_inserting_orm`. The other is by using
31+
the :class:`_sql.Insert` construct directly
32+
in a manner very similar to that described in this section; this use
33+
is introduced at :ref:`tutorial_orm_bulk`.
34+
3035

3136
The insert() SQL Expression Construct
3237
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -249,21 +254,13 @@ as in the example below that builds upon the example stated in
249254

250255
The RETURNING feature is also supported by UPDATE and DELETE statements,
251256
which will be introduced later in this tutorial.
252-
The RETURNING feature is generally [1]_ only
253-
supported for statement executions that use a single set of bound
254-
parameters; that is, it won't work with the "executemany" form introduced
255-
at :ref:`tutorial_multiple_parameters`. Additionally, some dialects
256-
such as the Oracle dialect only allow RETURNING to return a single row
257-
overall, meaning it won't work with "INSERT..FROM SELECT" nor will it
258-
work with multiple row :class:`_sql.Update` or :class:`_sql.Delete`
259-
forms.
260-
261-
.. [1] There is internal support for the
262-
:mod:`_postgresql.psycopg2` dialect to INSERT many rows at once
263-
and also support RETURNING, which is leveraged by the SQLAlchemy
264-
ORM. However this feature has not been generalized to all dialects
265-
and is not yet part of SQLAlchemy's regular API.
266257

258+
For INSERT statements, the RETURNING feature may be used
259+
both for single-row statements as well as for statements that INSERT
260+
multiple rows at once. Support for multiple-row INSERT with RETURNING
261+
is dialect specific, however is supported for all the dialects
262+
that are included in SQLAlchemy which support RETURNING. See the section
263+
:ref:`engine_insertmanyvalues` for background on this feature.
267264

268265

269266
.. seealso::

doc/build/tutorial/metadata.rst

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ Core-oriented style as well as an ORM-oriented style.
2626

2727
As with other sections, Core users can skip the ORM sections, but ORM users
2828
would best be familiar with these objects from both perspectives.
29+
The :class:`.Table` object discussed here is declared in a more indirect
30+
(and also fully Python-typed) way when using the ORM, however there is still
31+
a :class:`.Table` object within the ORM's configuration.
2932

3033

3134
.. rst-class:: core-header
@@ -35,17 +38,19 @@ Core-oriented style as well as an ORM-oriented style.
3538
Setting up MetaData with Table objects
3639
---------------------------------------
3740

38-
When we work with a relational database, the basic structure that we create and
39-
query from is known as a **table**. In SQLAlchemy, the "table" is represented
40-
by a Python object similarly named :class:`_schema.Table`.
41+
When we work with a relational database, the basic data-holding structure
42+
in the database which we query from is known a **table**.
43+
In SQLAlchemy, the database "table" may be represented
44+
directly by a Python object similarly named :class:`_schema.Table`.
4145

4246
To start using the SQLAlchemy Expression Language,
4347
we will want to have :class:`_schema.Table` objects constructed that represent
4448
all of the database tables we are interested in working with. Each
4549
:class:`_schema.Table` may be **declared**, meaning we explicitly spell out
4650
in source code what the table looks like, or may be **reflected**, which means
4751
we generate the object based on what's already present in a particular database.
48-
The two approaches can also be blended in many ways.
52+
The two approaches can also be blended in many ways, and also interact with
53+
ORM-centric styles of table declaration.
4954

5055
Whether we will declare or reflect our tables, we start out with a collection
5156
that will be where we place our tables known as the :class:`_schema.MetaData`
@@ -177,8 +182,8 @@ In the next section we will emit the completed DDL for the ``user`` and
177182
Emitting DDL to the Database
178183
----------------------------
179184

180-
We've constructed a fairly elaborate object hierarchy to represent
181-
two database tables, starting at the root :class:`_schema.MetaData`
185+
We've constructed a an object structure that represents
186+
two database tables in a database, starting at the root :class:`_schema.MetaData`
182187
object, then into two :class:`_schema.Table` objects, each of which hold
183188
onto a collection of :class:`_schema.Column` and :class:`_schema.Constraint`
184189
objects. This object structure will be at the center of most operations

doc/build/tutorial/orm_data_manipulation.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ we've made here is local to an ongoing transaction, which won't become
388388
permanent if we don't commit it. As rolling the transaction back is actually
389389
more interesting at the moment, we will do that in the next section.
390390

391+
.. _tutorial_orm_bulk:
391392

392393

393394
Bulk / Multi Row INSERT, upsert, UPDATE and DELETE

lib/sqlalchemy/sql/selectable.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@
130130
from .cache_key import _CacheKeyTraversalType
131131
from .compiler import SQLCompiler
132132
from .dml import Delete
133-
from .dml import Insert
134133
from .dml import Update
135134
from .elements import KeyedColumnElement
136135
from .elements import Label
@@ -3000,8 +2999,8 @@ def append_column(self, c: ColumnClause[Any]) -> None:
30002999
c.table = self
30013000

30023001
@util.preload_module("sqlalchemy.sql.dml")
3003-
def insert(self) -> Insert:
3004-
"""Generate an :func:`_expression.insert` construct against this
3002+
def insert(self) -> util.preloaded.sql_dml.Insert:
3003+
"""Generate an :class:`_sql.Insert` construct against this
30053004
:class:`_expression.TableClause`.
30063005
30073006
E.g.::

0 commit comments

Comments
 (0)