secondary="association",
backref="parents")
+.. warning:: When passed as a Python-evaluable string, the
+ :paramref:`.relationship.secondary` argument is interpreted using Python's
+ ``eval()`` function. **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**. See
+ :ref:`declarative_relationship_eval` for details on declarative
+ evaluation of :func:`.relationship` arguments.
+
+
.. _relationships_many_to_many_deletion:
Deleting Rows from the Many to Many Table
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship(User, primaryjoin=user_id == User.id)
+.. _declarative_relationship_eval:
+
+Evaluation of relationship arguments
+=====================================
+
In addition to the main argument for :func:`~sqlalchemy.orm.relationship`,
-other arguments which depend upon the columns present on an as-yet
-undefined class may also be specified as strings. These strings are
-evaluated as Python expressions. The full namespace available within
-this evaluation includes all classes mapped for this declarative base,
-as well as the contents of the ``sqlalchemy`` package, including
-expression functions like :func:`~sqlalchemy.sql.expression.desc` and
+other arguments which depend upon the columns present on an as-yet undefined
+class may also be specified as strings. For all of these arguments
+**including** the main argument prior to SQLAlchemy 1.3.16, these strings are
+**evaluated as Python expressions using Python's built-in eval() function.**
+
+The full namespace available within this evaluation includes all classes mapped
+for this declarative base, as well as the contents of the ``sqlalchemy``
+package, including expression functions like
+:func:`~sqlalchemy.sql.expression.desc` and
:attr:`~sqlalchemy.sql.expression.func`::
class User(Base):
order_by="desc(Address.email)",
primaryjoin="Address.user_id==User.id")
+.. warning::
+
+ The strings accepted by the following parameters:
+
+ :paramref:`.relationship.order_by`
+
+ :paramref:`.relationship.primaryjoin`
+
+ :paramref:`.relationship.secondaryjoin`
+
+ :paramref:`.relationship.secondary`
+
+ :paramref:`.relationship.remote_side`
+
+ :paramref:`.relationship.foreign_keys`
+
+ :paramref:`.relationship._user_defined_foreign_keys`
+
+ Are **evaluated as Python code expressions using eval(). DO NOT PASS
+ UNTRUSTED INPUT TO THESE ARGUMENTS.**
+
+ In addition, prior to version 1.3.16 of SQLAlchemy, the main
+ "argument" to :func:`.relationship` is also evaluated as Python
+ code. **DO NOT PASS UNTRUSTED INPUT TO THIS ARGUMENT.**
+
For the case where more than one module contains a class of the same name,
string class names can also be specified as module-qualified paths
within any of these string expressions::
billing_address = relationship("Address", foreign_keys="Customer.billing_address_id")
+.. warning:: When passed as a Python-evaluable string, the
+ :paramref:`.relationship.foreign_keys` argument is interpreted using Python's
+ ``eval()`` function. **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**. See
+ :ref:`declarative_relationship_eval` for details on declarative
+ evaluation of :func:`.relationship` arguments.
+
+
.. _relationship_primaryjoin:
Specifying Alternate Join Conditions
state = Column(String)
zip = Column(String)
-Within this string SQL expression, we made use of the :func:`.and_` conjunction construct to establish
-two distinct predicates for the join condition - joining both the ``User.id`` and
-``Address.user_id`` columns to each other, as well as limiting rows in ``Address``
-to just ``city='Boston'``. When using Declarative, rudimentary SQL functions like
-:func:`.and_` are automatically available in the evaluated namespace of a string
-:func:`.relationship` argument.
+Within this string SQL expression, we made use of the :func:`.and_` conjunction
+construct to establish two distinct predicates for the join condition - joining
+both the ``User.id`` and ``Address.user_id`` columns to each other, as well as
+limiting rows in ``Address`` to just ``city='Boston'``. When using
+Declarative, rudimentary SQL functions like :func:`.and_` are automatically
+available in the evaluated namespace of a string :func:`.relationship`
+argument.
+
+.. warning:: When passed as a Python-evaluable string, the
+ :paramref:`.relationship.primaryjoin` argument is interpreted using
+ Python's
+ ``eval()`` function. **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**. See
+ :ref:`declarative_relationship_eval` for details on declarative
+ evaluation of :func:`.relationship` arguments.
+
The custom criteria we use in a :paramref:`~.relationship.primaryjoin`
is generally only significant when SQLAlchemy is rendering SQL in
backref="left_nodes"
)
+.. warning:: When passed as a Python-evaluable string, the
+ :paramref:`.relationship.primaryjoin` and
+ :paramref:`.relationship.secondaryjoin` arguments are interpreted using
+ Python's ``eval()`` function. **DO NOT PASS UNTRUSTED INPUT TO THESE
+ STRINGS**. See :ref:`declarative_relationship_eval` for details on
+ declarative evaluation of :func:`.relationship` arguments.
+
+
A classical mapping situation here is similar, where ``node_to_node`` can be joined
to ``node.c.id``::
:paramref:`~.relationship.argument` may also be passed as a callable
function which is evaluated at mapper initialization time, and may
- be passed as a Python-evaluable string when using Declarative.
+ be passed as a string name when using Declarative.
+
+ .. warning:: Prior to SQLAlchemy 1.3.16, this value is interpreted
+ using Python's ``eval()`` function.
+ **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**.
+ See :ref:`declarative_relationship_eval` for details on
+ declarative evaluation of :func:`.relationship` arguments.
.. seealso::
present in the :class:`.MetaData` collection associated with the
parent-mapped :class:`.Table`.
+ .. warning:: When passed as a Python-evaluable string, the
+ argument is interpreted using Python's ``eval()`` function.
+ **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**.
+ See :ref:`declarative_relationship_eval` for details on
+ declarative evaluation of :func:`.relationship` arguments.
+
The :paramref:`~.relationship.secondary` keyword argument is
typically applied in the case where the intermediary :class:`.Table`
is not otherwise expressed in any direct class mapping. If the
and may be passed as a Python-evaluable string when using
Declarative.
+ .. warning:: When passed as a Python-evaluable string, the
+ argument is interpreted using Python's ``eval()`` function.
+ **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**.
+ See :ref:`declarative_relationship_eval` for details on
+ declarative evaluation of :func:`.relationship` arguments.
+
.. seealso::
:ref:`relationship_foreign_keys`
function which is evaluated at mapper initialization time, and may
be passed as a Python-evaluable string when using Declarative.
+ .. warning:: When passed as a Python-evaluable string, the
+ argument is interpreted using Python's ``eval()`` function.
+ **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**.
+ See :ref:`declarative_relationship_eval` for details on
+ declarative evaluation of :func:`.relationship` arguments.
+
:param passive_deletes=False:
Indicates loading behavior during delete operations.
and may be passed as a Python-evaluable string when using
Declarative.
+ .. warning:: When passed as a Python-evaluable string, the
+ argument is interpreted using Python's ``eval()`` function.
+ **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**.
+ See :ref:`declarative_relationship_eval` for details on
+ declarative evaluation of :func:`.relationship` arguments.
+
.. seealso::
:ref:`relationship_primaryjoin`
and may be passed as a Python-evaluable string when using
Declarative.
+ .. warning:: When passed as a Python-evaluable string, the
+ argument is interpreted using Python's ``eval()`` function.
+ **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**.
+ See :ref:`declarative_relationship_eval` for details on
+ declarative evaluation of :func:`.relationship` arguments.
+
.. seealso::
:ref:`self_referential` - in-depth explanation of how
and may be passed as a Python-evaluable string when using
Declarative.
+ .. warning:: When passed as a Python-evaluable string, the
+ argument is interpreted using Python's ``eval()`` function.
+ **DO NOT PASS UNTRUSTED INPUT TO THIS STRING**.
+ See :ref:`declarative_relationship_eval` for details on
+ declarative evaluation of :func:`.relationship` arguments.
+
.. seealso::
:ref:`relationship_primaryjoin`