diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-02-11 12:51:46 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2020-02-11 12:51:46 -0500 |
| commit | 4376c2e5b016e8dfec7bc1b0d2ebbebae737c063 (patch) | |
| tree | d16bca4088fada1399e354adc37bef6f0e64d9fd /lib/sqlalchemy/orm/relationships.py | |
| parent | 532ddb0fa717bc10c3a95b7ddf3a60bbfad7ac56 (diff) | |
| download | sqlalchemy-4376c2e5b016e8dfec7bc1b0d2ebbebae737c063.tar.gz | |
Begin to disallow back_populates with viewonly=True
A viewonly=True relationship should not be mutated and ideally
mutation itself would raise an error, but we're not there yet.
Warn when a viewonly is to be the target of a back_populates
as this only means that it should be locally mutated, which
by definition will not work as expected because post-flush
it will deliver doubled results, due to its state not being
reset.
Setting a relationship to viewonly=True which is also the target of a
back_populates or backref configuration will now emit a warning and
eventually be disallowed. back_populates refers specifically to mutation
of an attribute or collection, which is disallowed when the attribute is
subject to viewonly=True. The viewonly attribute is not subject to
persistence behaviors which means it will not reflect correct results
when it is locally mutated.
Fixes: #5149
Change-Id: Ie51382a82e1a0ff5f3cf2cdbded780e77ace7f5f
Diffstat (limited to 'lib/sqlalchemy/orm/relationships.py')
| -rw-r--r-- | lib/sqlalchemy/orm/relationships.py | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/lib/sqlalchemy/orm/relationships.py b/lib/sqlalchemy/orm/relationships.py index d745500c1..5573f7c9a 100644 --- a/lib/sqlalchemy/orm/relationships.py +++ b/lib/sqlalchemy/orm/relationships.py @@ -827,6 +827,19 @@ class RelationshipProperty(StrategizedProperty): the full set of related objects, to prevent modifications of the collection from resulting in persistence operations. + .. warning:: The viewonly=True relationship should not be mutated + in Python; that means, elements should not be added or removed + from collections nor should a many-to-one or one-to-one attribute + be altered in Python. The viewonly=True relationship should only + be accessed via read. Towards this behavior, it is also not + appropriate for the viewonly=True relationship to have any kind + of persistence cascade settings, nor should it be the target of + either :paramref:`.relationship.backref` or + :paramref:`.relationship.back_populates`, as backrefs imply + in-Python mutation of the attribute. SQLAlchemy may emit + warnings for some or all of these conditions as of the 1.3 and + 1.4 series of SQLAlchemy and will eventually be disallowed. + :param omit_join: Allows manual control over the "selectin" automatic join optimization. Set to ``False`` to disable the "omit join" feature @@ -1841,6 +1854,14 @@ class RelationshipProperty(StrategizedProperty): def _add_reverse_property(self, key): other = self.mapper.get_property(key, _configure_mappers=False) + if other.viewonly: + util.warn_limited( + "Setting backref / back_populates on relationship %s to refer " + "to viewonly relationship %s will be deprecated in SQLAlchemy " + "1.4, and will be disallowed in a future release. " + "viewonly relationships should not be mutated", + (self, other), + ) self._reverse_property.add(other) other._reverse_property.add(self) |
