diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-01-14 18:06:26 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-01-14 18:06:26 -0500 |
commit | 1f7a1f777d8fe1bdea1e793c8ec8ebb7c625e347 (patch) | |
tree | c46674ad4a3fde2aaf9eb8238650879161f6eea7 /doc/build/orm/tutorial.rst | |
parent | 0ff3f95d5b41335c977e1bdbe88b7dfd4ae581e1 (diff) | |
download | sqlalchemy-1f7a1f777d8fe1bdea1e793c8ec8ebb7c625e347.tar.gz |
- A deep improvement to the recently added :meth:`.TextClause.columns`
method, and its interaction with result-row processing, now allows
the columns passed to the method to be positionally matched with the
result columns in the statement, rather than matching on name alone.
The advantage to this includes that when linking a textual SQL statement
to an ORM or Core table model, no system of labeling or de-duping of
common column names needs to occur, which also means there's no need
to worry about how label names match to ORM columns and so-forth. In
addition, the :class:`.ResultProxy` has been further enhanced to
map column and string keys to a row with greater precision in some
cases. fixes #3501
- reorganize the initialization of ResultMetaData for readability
and complexity; use the name "cursor_description", define the
task of "merging" cursor_description with compiled column information
as its own function, and also define "name extraction" as a separate task.
- fully change the name we use in the "ambiguous column" error to be the
actual name that was ambiguous, modify the C ext also
Diffstat (limited to 'doc/build/orm/tutorial.rst')
-rw-r--r-- | doc/build/orm/tutorial.rst | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/doc/build/orm/tutorial.rst b/doc/build/orm/tutorial.rst index 53f161003..6e98dfc9c 100644 --- a/doc/build/orm/tutorial.rst +++ b/doc/build/orm/tutorial.rst @@ -965,10 +965,12 @@ method: (224, 'fred') {stop}<User(name='fred', fullname='Fred Flinstone', password='blah')> -To use an entirely string-based statement, using -:meth:`~sqlalchemy.orm.query.Query.from_statement()`; just ensure that the -columns clause of the statement contains the column names normally used by the -mapper (below illustrated using an asterisk): +To use an entirely string-based statement, a :func:`.text` construct +representing a complete statement can be passed to +:meth:`~sqlalchemy.orm.query.Query.from_statement()`. Without additional +specifiers, the columns in the string SQL are matched to the model columns +based on name, such as below where we use just an asterisk to represent +loading all columns: .. sourcecode:: python+sql @@ -979,19 +981,37 @@ mapper (below illustrated using an asterisk): ('ed',) {stop}[<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>] -Or alternatively, specify how the columns map to the :func:`.text` construct -explicitly using the :meth:`.TextClause.columns` method: +Matching columns on name works for simple cases but can become unwieldy when +dealing with complex statements that contain duplicate column names or when +using anonymized ORM constructs that don't easily match to specific names. +Additionally, there is typing behavior present in our mapped columns that +we might find necessary when handling result rows. For these cases, +the :func:`~.expression.text` construct allows us to link its textual SQL +to Core or ORM-mapped column expressions positionally; we can achieve this +by passing column expressions as positional arguments to the +:meth:`.TextClause.columns` method: .. sourcecode:: python+sql - >>> stmt = text("SELECT name, id FROM users where name=:name") - >>> stmt = stmt.columns(User.name, User.id) + >>> stmt = text("SELECT name, id, fullname, password " + ... "FROM users where name=:name") + >>> stmt = stmt.columns(User.name, User.id, User.fullname, User.password) {sql}>>> session.query(User).from_statement(stmt).params(name='ed').all() - SELECT name, id FROM users where name=? + SELECT name, id, fullname, password FROM users where name=? ('ed',) {stop}[<User(name='ed', fullname='Ed Jones', password='f8s7ccs')>] -We can choose columns to return individually as well, as in any other case: +.. versionadded:: 1.1 + + The :meth:`.TextClause.columns` method now accepts column expressions + which will be matched positionally to a plain text SQL result set, + eliminating the need for column names to match or even be unique in the + SQL statement. + +When selecting from a :func:`~.expression.text` construct, the :class:`.Query` +may still specify what columns and entities are to be returned; instead of +``query(User)`` we can also ask for the columns individually, as in +any other case: .. sourcecode:: python+sql @@ -1008,11 +1028,6 @@ We can choose columns to return individually as well, as in any other case: :ref:`sqlexpression_text` - The :func:`.text` construct explained from the perspective of Core-only queries. -.. versionchanged:: 1.0.0 - The :class:`.Query` construct emits warnings when string SQL - fragments are coerced to :func:`.text`, and :func:`.text` should - be used explicitly. See :ref:`migration_2992` for background. - Counting -------- |