Merge "Load all eager relationships on 'before_commit' event"

This commit is contained in:
Jenkins 2017-03-28 09:40:24 +00:00 committed by Gerrit Code Review
commit 9364f58ec5
2 changed files with 40 additions and 0 deletions

View File

@ -31,6 +31,7 @@ import six
import sqlalchemy
from sqlalchemy import event # noqa
from sqlalchemy import exc as sql_exc
from sqlalchemy import orm
from sqlalchemy.orm import exc
from neutron._i18n import _LE
@ -261,3 +262,33 @@ def sqla_remove_all():
# already removed
pass
del _REGISTERED_SQLA_EVENTS[:]
@event.listens_for(orm.session.Session, "before_commit")
def load_one_to_manys(session):
# TODO(kevinbenton): we should be able to remove this after we
# have eliminated all places where related objects are constructed
# using a key rather than a relationship.
for new_object in session.new:
state = sqlalchemy.inspect(new_object)
# set up relationship loading so that we can call lazy
# loaders on the object even though the ".key" is not set up yet
# (normally happens by in after_flush_postexec, but we're trying
# to do this more succinctly). in this context this is only
# setting a simple flag on the object's state.
session.enable_relationship_loading(new_object)
# look for eager relationships and do normal load.
# For relationships where the related object is also
# in the session these lazy loads will pull from the
# identity map and not emit SELECT. Otherwise, we are still
# local in the transaction so a normal SELECT load will work fine.
for relationship_attr in state.mapper.relationships:
if relationship_attr.lazy not in ('joined', 'subquery'):
# we only want to automatically load relationships that would
# automatically load during a lookup operation
continue
if relationship_attr.key not in state.dict:
getattr(new_object, relationship_attr.key)
assert relationship_attr.key in state.dict

View File

@ -6061,6 +6061,15 @@ class TestSubnetPoolsV2(NeutronDbPluginV2TestCase):
class DbModelMixin(object):
"""DB model tests."""
def test_make_network_dict_outside_engine_facade_manager(self):
ctx = context.get_admin_context()
with db_api.context_manager.writer.using(ctx):
network = models_v2.Network(name="net_net", status="OK",
admin_state_up=True)
ctx.session.add(network)
pl = db_base_plugin_common.DbBasePluginCommon()
self.assertFalse(pl._make_network_dict(network, context=ctx)['shared'])
def test_repr(self):
"""testing the string representation of 'model' classes."""
network = models_v2.Network(name="net_net", status="OK",