Skip to content

Commit 7082e4c

Browse files
committed
Clarify how ORM rows are returned in the tutorial
The ORM querying guide discussed how rows are returned but the tutorial fails to introduce this important concept. Fixes: sqlalchemy#5706 Change-Id: I8c9585e28841b5dd86f4ab642f57cbc763635425
1 parent ea3f4fa commit 7082e4c

1 file changed

Lines changed: 53 additions & 9 deletions

File tree

doc/build/tutorial/data.rst

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -425,22 +425,66 @@ in the same way as if we had used ``user_table`` directly::
425425
{opensql}SELECT user_account.id, user_account.name, user_account.fullname
426426
FROM user_account
427427

428-
To select from individual columns using ORM entities, the class-bound
429-
attributes can be passed directly which are resolved into the
428+
When executing a statement like the above using the ORM :meth:`_orm.Session.execute`
429+
method, there is an important difference when we select from a full entity
430+
such as ``User``, as opposed to ``user_table``, which is that the **entity
431+
itself is returned as a single column within each row**. That is, when we fetch rows from
432+
the above statement, as there is only the ``User`` entity in the list of
433+
things to fetch, we get back :class:`_engine.Row` objects that have only one column, which contain
434+
instances of the ``User`` class::
435+
436+
>>> row = session.execute(select(User)).first()
437+
{opensql}BEGIN...
438+
SELECT user_account.id, user_account.name, user_account.fullname
439+
FROM user_account
440+
[...] (){stop}
441+
>>> row
442+
(User(id=1, name='spongebob', fullname='Spongebob Squarepants'),)
443+
444+
The above :class:`_engine.Row` has just one column, representing the ``User`` entity::
445+
446+
>>> row[0]
447+
User(id=1, name='spongebob', fullname='Spongebob Squarepants')
448+
449+
Alternatively, we can select individual columns from an ORM entity, by
450+
using the class-bound
451+
attributes; when these are passed to a construct such as :func:`_sql.select`,
452+
they are resolved into the
430453
:class:`_schema.Column` or other SQL expression represented by each attribute::
431454

432455
>>> print(select(User.name, User.fullname))
433456
{opensql}SELECT user_account.name, user_account.fullname
434457
FROM user_account
435458

436-
.. tip::
459+
When we invoke *this* statement using :meth:`_orm.Session.execute`, we now
460+
receive rows that have individual columns per value::
461+
462+
>>> row = session.execute(select(User.name, User.fullname)).first()
463+
{opensql}SELECT user_account.name, user_account.fullname
464+
FROM user_account
465+
[...] (){stop}
466+
>>> row
467+
('spongebob', 'Spongebob Squarepants')
468+
469+
The approaches can also be mixed, as below where we SELECT the ``name``
470+
attribute of the ``User`` entity as the first column, and combine it with full
471+
``Address`` entities in the second column::
472+
473+
>>> session.execute(
474+
... select(User.name, Address).
475+
... where(User.id==Address.user_id).
476+
... order_by(Address.id)
477+
... ).all()
478+
{opensql}SELECT user_account.name, address.id, address.email_address, address.user_id
479+
FROM user_account, address
480+
WHERE user_account.id = address.user_id ORDER BY address.id
481+
[...] (){stop}
482+
[('spongebob', Address(id=1, email_address='spongebob@sqlalchemy.org')),
483+
('sandy', Address(id=2, email_address='sandy@sqlalchemy.org')),
484+
('sandy', Address(id=3, email_address='sandy@squirrelpower.org'))]
437485

438-
When ORM-related objects are used within the :class:`_sql.Select`
439-
construct, they are resolved into the underlying :class:`_schema.Table` and
440-
:class:`_schema.Column` and similar Core constructs they represent; at the
441-
same time, they apply a **plugin** to the core :class:`_sql.Select`
442-
construct such that a new set of ORM-specific behaviors make take
443-
effect when the construct is being compiled.
486+
Approaches towards selecting ORM entities and columns as well as common methods
487+
for converting rows are discussed further at :ref:`orm_queryguide_select_columns`.
444488

445489
.. seealso::
446490

0 commit comments

Comments
 (0)