Merge "Load all eager relationships on 'before_commit' event"
This commit is contained in:
commit
9364f58ec5
@ -31,6 +31,7 @@ import six
|
|||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
from sqlalchemy import event # noqa
|
from sqlalchemy import event # noqa
|
||||||
from sqlalchemy import exc as sql_exc
|
from sqlalchemy import exc as sql_exc
|
||||||
|
from sqlalchemy import orm
|
||||||
from sqlalchemy.orm import exc
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
from neutron._i18n import _LE
|
from neutron._i18n import _LE
|
||||||
@ -261,3 +262,33 @@ def sqla_remove_all():
|
|||||||
# already removed
|
# already removed
|
||||||
pass
|
pass
|
||||||
del _REGISTERED_SQLA_EVENTS[:]
|
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
|
||||||
|
@ -6061,6 +6061,15 @@ class TestSubnetPoolsV2(NeutronDbPluginV2TestCase):
|
|||||||
|
|
||||||
class DbModelMixin(object):
|
class DbModelMixin(object):
|
||||||
"""DB model tests."""
|
"""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):
|
def test_repr(self):
|
||||||
"""testing the string representation of 'model' classes."""
|
"""testing the string representation of 'model' classes."""
|
||||||
network = models_v2.Network(name="net_net", status="OK",
|
network = models_v2.Network(name="net_net", status="OK",
|
||||||
|
Loading…
Reference in New Issue
Block a user