diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2015-08-11 13:05:17 -0400 |
---|---|---|
committer | Stefan Urbanek <stefan@agentfarms.net> | 2015-08-25 23:56:10 -0700 |
commit | 29ab9bcfff4f6068033eafc2b1b92692331a7363 (patch) | |
tree | f083b1affc75c17f1cf76eadc268bd4427c6b1a3 | |
parent | d187407048c4b5e1f73a952986753823c886093f (diff) | |
download | sqlalchemy-29ab9bcfff4f6068033eafc2b1b92692331a7363.tar.gz |
- Fixed 1.0 regression where the "noload" loader strategy would fail
to function for a many-to-one relationship. The loader used an
API to place "None" into the dictionary which no longer actually
writes a value; this is a side effect of :ticket:`3061`.
- remove InstanceState._initialize() totally, it's used nowhere
else and no longer does what it says it does
- fill in fowards-port version ids throughout the changes for 1.0.9
-rw-r--r-- | doc/build/changelog/changelog_10.rst | 12 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/attributes.py | 5 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/state.py | 6 | ||||
-rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 5 | ||||
-rw-r--r-- | test/orm/test_mapper.py | 18 |
5 files changed, 39 insertions, 7 deletions
diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index ad9c1473d..ad8805299 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -19,8 +19,19 @@ :version: 1.0.9 .. change:: + :tags: bug, orm + :tickets: 3510 + :versions: 1.1.0b1 + + Fixed 1.0 regression where the "noload" loader strategy would fail + to function for a many-to-one relationship. The loader used an + API to place "None" into the dictionary which no longer actually + writes a value; this is a side effect of :ticket:`3061`. + + .. change:: :tags: bug, sybase :tickets: 3508, 3509 + :versions: 1.1.0b1 Fixed two issues regarding Sybase reflection, allowing tables without primary keys to be reflected as well as ensured that @@ -32,6 +43,7 @@ .. change:: :tags: bug, postgresql :pullreq: github:190 + :versions: 1.1.0b1 An adjustment to the new Postgresql feature of reflecting storage options and USING of :ticket:`3455` released in 1.0.6, diff --git a/lib/sqlalchemy/orm/attributes.py b/lib/sqlalchemy/orm/attributes.py index a45c22394..5440d6b5d 100644 --- a/lib/sqlalchemy/orm/attributes.py +++ b/lib/sqlalchemy/orm/attributes.py @@ -551,6 +551,11 @@ class AttributeImpl(object): def initialize(self, state, dict_): """Initialize the given state's attribute with an empty value.""" + # As of 1.0, we don't actually set a value in + # dict_. This is so that the state of the object does not get + # modified without emitting the appropriate events. + + return None def get(self, state, dict_, passive=PASSIVE_OFF): diff --git a/lib/sqlalchemy/orm/state.py b/lib/sqlalchemy/orm/state.py index 6034e74de..61d1ad29d 100644 --- a/lib/sqlalchemy/orm/state.py +++ b/lib/sqlalchemy/orm/state.py @@ -374,12 +374,6 @@ class InstanceState(interfaces.InspectionAttr): state_dict['manager'](self, inst, state_dict) - def _initialize(self, key): - """Set this attribute to an empty value or collection, - based on the AttributeImpl in use.""" - - self.manager.get_impl(key).initialize(self, self.dict) - def _reset(self, dict_, key): """Remove the given attribute and any callables associated with it.""" diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index b9ef5808b..67dac1ccc 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -346,7 +346,10 @@ class NoLoader(AbstractRelationshipLoader): self, context, path, loadopt, mapper, result, adapter, populators): def invoke_no_load(state, dict_, row): - state._initialize(self.key) + if self.uselist: + state.manager.get_impl(self.key).initialize(state, dict_) + else: + dict_[self.key] = None populators["new"].append((self.key, invoke_no_load)) diff --git a/test/orm/test_mapper.py b/test/orm/test_mapper.py index 8dc23efd0..6845ababb 100644 --- a/test/orm/test_mapper.py +++ b/test/orm/test_mapper.py @@ -2698,6 +2698,24 @@ class NoLoadTest(_fixtures.FixtureTest): {'id': 7, 'addresses': (Address, [{'id': 1}])}, ) + def test_m2o_noload_option(self): + Address, addresses, users, User = ( + self.classes.Address, + self.tables.addresses, + self.tables.users, + self.classes.User) + mapper(Address, addresses, properties={ + 'user': relationship(User) + }) + mapper(User, users) + s = Session() + a1 = s.query(Address).filter_by(id=1).options( + sa.orm.noload('user')).first() + + def go(): + eq_(a1.user, None) + self.sql_count_(0, go) + class RequirementsTest(fixtures.MappedTest): |