summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/sql
diff options
context:
space:
mode:
Diffstat (limited to 'lib/sqlalchemy/sql')
-rw-r--r--lib/sqlalchemy/sql/elements.py25
-rw-r--r--lib/sqlalchemy/sql/schema.py36
-rw-r--r--lib/sqlalchemy/sql/selectable.py81
3 files changed, 105 insertions, 37 deletions
diff --git a/lib/sqlalchemy/sql/elements.py b/lib/sqlalchemy/sql/elements.py
index dc3e5f476..59f3fa86b 100644
--- a/lib/sqlalchemy/sql/elements.py
+++ b/lib/sqlalchemy/sql/elements.py
@@ -1641,12 +1641,9 @@ class TextClause(
t = text("EXEC my_procedural_thing()").\
execution_options(autocommit=True)
- Note that SQLAlchemy's usual "autocommit" behavior applies to
- :func:`_expression.text` constructs implicitly - that is,
- statements which begin
- with a phrase such as ``INSERT``, ``UPDATE``, ``DELETE``,
- or a variety of other phrases specific to certain backends, will
- be eligible for autocommit if no transaction is in progress.
+ .. deprecated:: 1.4 The "autocommit" execution option is deprecated
+ and will be removed in SQLAlchemy 2.0. See
+ :ref:`migration_20_autocommit` for discussion.
:param text:
the text of the SQL statement to be created. Use ``:<param>``
@@ -3401,12 +3398,18 @@ class CollectionAggregate(UnaryExpression):
# mysql '5 = ANY (SELECT value FROM table)'
expr = 5 == any_(select(table.c.value))
- .. versionadded:: 1.1
+ The operator is more conveniently available from any
+ :class:`_sql.ColumnElement` object that makes use of the
+ :class:`_types.ARRAY` datatype::
+
+ expr = mytable.c.somearray.any(5)
.. seealso::
:func:`_expression.all_`
+ :meth:`_types.ARRAY.any`
+
"""
expr = coercions.expect(roles.ExpressionElementRole, expr)
@@ -3432,12 +3435,18 @@ class CollectionAggregate(UnaryExpression):
# mysql '5 = ALL (SELECT value FROM table)'
expr = 5 == all_(select(table.c.value))
- .. versionadded:: 1.1
+ The operator is more conveniently available from any
+ :class:`_sql.ColumnElement` object that makes use of the
+ :class:`_types.ARRAY` datatype::
+
+ expr = mytable.c.somearray.all(5)
.. seealso::
:func:`_expression.any_`
+ :meth:`_types.ARRAY.Comparator.all`
+
"""
expr = coercions.expect(roles.ExpressionElementRole, expr)
diff --git a/lib/sqlalchemy/sql/schema.py b/lib/sqlalchemy/sql/schema.py
index e9654fb1f..496f8d9fb 100644
--- a/lib/sqlalchemy/sql/schema.py
+++ b/lib/sqlalchemy/sql/schema.py
@@ -211,11 +211,12 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
objects that were
explicitly specified.
- .. versionchanged:: 1.0.0 setting the
- :paramref:`_schema.Table.autoload_with`
- parameter implies that :paramref:`_schema.Table.autoload`
- will default
- to True.
+ .. deprecated:: 1.4
+
+ The autoload parameter is deprecated and will be removed in
+ version 2.0. Please use the
+ :paramref:`_schema.Table`autoload_with` parameter, passing an
+ engine or connection.
.. seealso::
@@ -251,18 +252,8 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
:func:`_sa.inspect`
against one, with which this :class:`_schema.Table`
object will be reflected.
- When set to a non-None value, it implies that
- :paramref:`_schema.Table.autoload` is ``True``. If left unset, but
- :paramref:`_schema.Table.autoload` is explicitly set to ``True``,
- an autoload
- operation will attempt to proceed by locating an
- :class:`_engine.Engine` or
- :class:`_engine.Connection` bound to the underlying
- :class:`_schema.MetaData` object.
-
- .. seealso::
-
- :paramref:`_schema.Table.autoload`
+ When set to a non-None value, the autoload process will take place
+ for this table against the given engine or connection.
:param extend_existing: When ``True``, indicates that if this
:class:`_schema.Table` is already present in the given
@@ -311,7 +302,6 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
Table("mytable", metadata,
Column('y', Integer),
extend_existing=True,
- autoload=True,
autoload_with=engine
)
@@ -407,7 +397,7 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
t = Table(
'sometable',
- autoload=True,
+ autoload_with=engine,
listeners=[
('column_reflect', listen_for_reflect)
])
@@ -488,7 +478,13 @@ class Table(DialectKWArgs, SchemaItem, TableClause):
mustexist=(
"1.4",
"Deprecated alias of :paramref:`_schema.Table.must_exist`",
- )
+ ),
+ autoload=(
+ "2.0",
+ "The autoload parameter is deprecated and will be removed in "
+ "version 2.0. Please use the "
+ "autoload_with parameter, passing an engine or connection.",
+ ),
)
def __new__(cls, *args, **kw):
if not args:
diff --git a/lib/sqlalchemy/sql/selectable.py b/lib/sqlalchemy/sql/selectable.py
index c78b1ec57..9440fc48b 100644
--- a/lib/sqlalchemy/sql/selectable.py
+++ b/lib/sqlalchemy/sql/selectable.py
@@ -4391,13 +4391,41 @@ class Select(
and apply generatively, returning the newly resulting
:class:`_expression.Select`.
- .. versionchanged:: 1.4 :meth:`_expression.Select.join` now modifies
- the FROM list of the :class:`.Select` object in place, rather than
- implicitly producing a subquery.
+ E.g.::
+
+ stmt = select(user_table).join(address_table, user_table.c.id == address_table.c.user_id)
+
+ The above statement generages SQL similar to::
+
+ SELECT user.id, user.name FROM user JOIN address ON user.id = address.user_id
+
+ .. versionchanged:: 1.4 :meth:`_expression.Select.join` now creates
+ a :class:`_sql.Join` object between a :class:`_sql.FromClause`
+ source that is within the FROM clause of the existing SELECT,
+ and a given target :class:`_sql.FromClause`, and then adds
+ this :class:`_sql.Join` to the FROM clause of the newly generated
+ SELECT statement. This is completely reworked from the behavior
+ in 1.3, which would instead create a subquery of the entire
+ :class:`_expression.Select` and then join that subquery to the
+ target.
+
+ This is a **backwards incompatible change** as the previous behavior
+ was mostly useless, producing an unnamed subquery rejected by
+ most databases in any case. The new behavior is modeled after
+ that of the very successful :meth:`_orm.Query.join` method in the
+ ORM, in order to support the functionality of :class:`_orm.Query`
+ being available by using a :class:`_sql.Select` object with an
+ :class:`_orm.Session`.
+
+ See the notes for this change at :ref:`change_select_join`.
+
:param target: target table to join towards
- :param onclause: ON clause of the join.
+ :param onclause: ON clause of the join. If omitted, an ON clause
+ is generated automatically based on the :class:`_schema.ForeignKey`
+ linkages between the two tables, if one can be unambiguously
+ determined, otherwise an error is raised.
:param isouter: if True, generate LEFT OUTER join. Same as
:meth:`_expression.Select.outerjoin`.
@@ -4408,7 +4436,9 @@ class Select(
:meth:`_expression.Select.join_from`
- """
+ :meth:`_expression.Select.outerjoin`
+
+ """ # noqa: E501
target = coercions.expect(
roles.JoinTargetRole, target, apply_propagate_attrs=self
)
@@ -4422,11 +4452,22 @@ class Select(
def join_from(
self, from_, target, onclause=None, isouter=False, full=False
):
- r"""Create a SQL JOIN against this :class:`_expresson.Select`
+ r"""Create a SQL JOIN against this :class:`_expression.Select`
object's criterion
and apply generatively, returning the newly resulting
:class:`_expression.Select`.
+ E.g.::
+
+ stmt = select(user_table, address_table).join_from(
+ user_table, address_table, user_table.c.id == address_table.c.user_id
+ )
+
+ The above statement generages SQL similar to::
+
+ SELECT user.id, user.name, address.id, address.email, address.user_id
+ FROM user JOIN address ON user.id = address.user_id
+
.. versionadded:: 1.4
:param from\_: the left side of the join, will be rendered in the
@@ -4446,7 +4487,8 @@ class Select(
:meth:`_expression.Select.join`
- """
+ """ # noqa: E501
+
# note the order of parsing from vs. target is important here, as we
# are also deriving the source of the plugin (i.e. the subject mapper
# in an ORM query) which should favor the "from_" over the "target"
@@ -4470,8 +4512,29 @@ class Select(
Parameters are the same as that of :meth:`_expression.Select.join`.
.. versionchanged:: 1.4 :meth:`_expression.Select.outerjoin` now
- modifies the FROM list of the :class:`.Select` object in place,
- rather than implicitly producing a subquery.
+ creates a :class:`_sql.Join` object between a
+ :class:`_sql.FromClause` source that is within the FROM clause of
+ the existing SELECT, and a given target :class:`_sql.FromClause`,
+ and then adds this :class:`_sql.Join` to the FROM clause of the
+ newly generated SELECT statement. This is completely reworked
+ from the behavior in 1.3, which would instead create a subquery of
+ the entire
+ :class:`_expression.Select` and then join that subquery to the
+ target.
+
+ This is a **backwards incompatible change** as the previous behavior
+ was mostly useless, producing an unnamed subquery rejected by
+ most databases in any case. The new behavior is modeled after
+ that of the very successful :meth:`_orm.Query.join` method in the
+ ORM, in order to support the functionality of :class:`_orm.Query`
+ being available by using a :class:`_sql.Select` object with an
+ :class:`_orm.Session`.
+
+ See the notes for this change at :ref:`change_select_join`.
+
+ .. seealso::
+
+ :meth:`_expression.Select.join`
"""
return self.join(target, onclause=onclause, isouter=True, full=full,)