Cleanup _find_related_obj
All of the additional lookup logic was essentially duplicating a relationship property of 'load_on_pending=True', which tells SQLAlchemy to lookup the relationship during object creation [1]. So we can dump all of this logic and just use that option. 1. http://docs.sqlalchemy.org/en/latest/orm/relationship_api.html #sqlalchemy.orm.relationship.params.load_on_pending Related: blueprint push-notifications Change-Id: I0e495a50f5cab9b6449825039d7683d77de1e763
This commit is contained in:
parent
d46636112f
commit
6dee4c5942
@ -41,6 +41,6 @@ class ExtraDhcpOpt(model_base.BASEV2, model_base.HasId):
|
||||
# Add a relationship to the Port model in order to instruct SQLAlchemy to
|
||||
# eagerly load extra_dhcp_opts bindings
|
||||
ports = orm.relationship(
|
||||
models_v2.Port,
|
||||
models_v2.Port, load_on_pending=True,
|
||||
backref=orm.backref("dhcp_opts", lazy='subquery', cascade='delete'))
|
||||
revises_on_change = ('ports', )
|
||||
|
@ -25,7 +25,7 @@ class AllowedAddressPair(model_base.BASEV2):
|
||||
ip_address = sa.Column(sa.String(64), nullable=False, primary_key=True)
|
||||
|
||||
port = orm.relationship(
|
||||
models_v2.Port,
|
||||
models_v2.Port, load_on_pending=True,
|
||||
backref=orm.backref("allowed_address_pairs",
|
||||
lazy="subquery", cascade="delete"))
|
||||
revises_on_change = ('port', )
|
||||
|
@ -29,6 +29,7 @@ class NetworkDNSDomain(model_base.BASEV2):
|
||||
# Add a relationship to the Network model in order to instruct
|
||||
# SQLAlchemy to eagerly load this association
|
||||
network = orm.relationship(models_v2.Network,
|
||||
load_on_pending=True,
|
||||
backref=orm.backref("dns_domain",
|
||||
lazy='joined',
|
||||
uselist=False,
|
||||
@ -57,6 +58,7 @@ class FloatingIPDNS(model_base.BASEV2):
|
||||
# Add a relationship to the FloatingIP model in order to instruct
|
||||
# SQLAlchemy to eagerly load this association
|
||||
floatingip = orm.relationship(l3_models.FloatingIP,
|
||||
load_on_pending=True,
|
||||
backref=orm.backref("dns",
|
||||
lazy='joined',
|
||||
uselist=False,
|
||||
@ -85,6 +87,7 @@ class PortDNS(model_base.BASEV2):
|
||||
# Add a relationship to the Port model in order to instruct
|
||||
# SQLAlchemy to eagerly load this association
|
||||
port = orm.relationship(models_v2.Port,
|
||||
load_on_pending=True,
|
||||
backref=orm.backref("dns",
|
||||
lazy='joined',
|
||||
uselist=False,
|
||||
|
@ -32,7 +32,7 @@ class ExternalNetwork(model_base.BASEV2):
|
||||
# Add a relationship to the Network model in order to instruct
|
||||
# SQLAlchemy to eagerly load this association
|
||||
network = orm.relationship(
|
||||
models_v2.Network,
|
||||
models_v2.Network, load_on_pending=True,
|
||||
backref=orm.backref("external", lazy='joined',
|
||||
uselist=False, cascade='delete'))
|
||||
revises_on_change = ('network', )
|
||||
|
@ -57,7 +57,7 @@ class Router(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
sa.ForeignKey("flavors.id"), nullable=True)
|
||||
attached_ports = orm.relationship(
|
||||
RouterPort,
|
||||
backref='router',
|
||||
backref=orm.backref('router', load_on_pending=True),
|
||||
lazy='dynamic')
|
||||
l3_agents = orm.relationship(
|
||||
'Agent', lazy='subquery', viewonly=True,
|
||||
@ -111,7 +111,7 @@ class RouterRoute(model_base.BASEV2, models_v2.Route):
|
||||
ondelete="CASCADE"),
|
||||
primary_key=True)
|
||||
|
||||
router = orm.relationship(Router,
|
||||
router = orm.relationship(Router, load_on_pending=True,
|
||||
backref=orm.backref("route_list",
|
||||
lazy='subquery',
|
||||
cascade='delete'))
|
||||
|
@ -42,7 +42,7 @@ class RouterExtraAttributes(model_base.BASEV2):
|
||||
availability_zone_hints = sa.Column(sa.String(255))
|
||||
|
||||
router = orm.relationship(
|
||||
'Router',
|
||||
'Router', load_on_pending=True,
|
||||
backref=orm.backref("extra_attributes", lazy='joined',
|
||||
uselist=False, cascade='delete'))
|
||||
revises_on_change = ('router', )
|
||||
|
@ -26,7 +26,7 @@ class PortBindingPort(model_base.BASEV2):
|
||||
primary_key=True)
|
||||
host = sa.Column(sa.String(255), nullable=False)
|
||||
port = orm.relationship(
|
||||
models_v2.Port,
|
||||
models_v2.Port, load_on_pending=True,
|
||||
backref=orm.backref("portbinding",
|
||||
lazy='joined', uselist=False,
|
||||
cascade='delete'))
|
||||
|
@ -58,7 +58,7 @@ class SecurityGroupPortBinding(model_base.BASEV2):
|
||||
# Add a relationship to the Port model in order to instruct SQLAlchemy to
|
||||
# eagerly load security group bindings
|
||||
ports = orm.relationship(
|
||||
models_v2.Port,
|
||||
models_v2.Port, load_on_pending=True,
|
||||
backref=orm.backref("security_groups",
|
||||
lazy='joined', cascade='delete'))
|
||||
|
||||
@ -85,7 +85,7 @@ class SecurityGroupRule(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
port_range_max = sa.Column(sa.Integer)
|
||||
remote_ip_prefix = sa.Column(sa.String(255))
|
||||
security_group = orm.relationship(
|
||||
SecurityGroup,
|
||||
SecurityGroup, load_on_pending=True,
|
||||
backref=orm.backref('rules', cascade='all,delete', lazy='subquery'),
|
||||
primaryjoin="SecurityGroup.id==SecurityGroupRule.security_group_id")
|
||||
source_group = orm.relationship(
|
||||
|
@ -70,7 +70,8 @@ class SegmentHostMapping(model_base.BASEV2):
|
||||
# Add a relationship to the NetworkSegment model in order to instruct
|
||||
# SQLAlchemy to eagerly load this association
|
||||
network_segment = orm.relationship(
|
||||
NetworkSegment, backref=orm.backref("segment_host_mapping",
|
||||
lazy='subquery',
|
||||
cascade='delete'))
|
||||
NetworkSegment, load_on_pending=True,
|
||||
backref=orm.backref("segment_host_mapping",
|
||||
lazy='subquery',
|
||||
cascade='delete'))
|
||||
revises_on_change = ('network_segment', )
|
||||
|
@ -31,7 +31,7 @@ class SubnetServiceType(model_base.BASEV2):
|
||||
# Service types must be valid device owners, therefore share max length
|
||||
service_type = sa.Column(sa.String(
|
||||
length=db_const.DEVICE_OWNER_FIELD_SIZE))
|
||||
subnet = orm.relationship(models_v2.Subnet,
|
||||
subnet = orm.relationship(models_v2.Subnet, load_on_pending=True,
|
||||
backref=orm.backref('service_types',
|
||||
lazy='subquery',
|
||||
cascade='all, delete-orphan',
|
||||
|
@ -26,6 +26,6 @@ class Tag(model_base.BASEV2):
|
||||
nullable=False, primary_key=True)
|
||||
tag = sa.Column(sa.String(60), nullable=False, primary_key=True)
|
||||
standard_attr = orm.relationship(
|
||||
'StandardAttribute',
|
||||
'StandardAttribute', load_on_pending=True,
|
||||
backref=orm.backref('tags', lazy='subquery', viewonly=True))
|
||||
revises_on_change = ('standard_attr', )
|
||||
|
@ -78,7 +78,10 @@ class Port(standard_attr.HasStandardAttributes, model_base.BASEV2,
|
||||
name = sa.Column(sa.String(db_const.NAME_FIELD_SIZE))
|
||||
network_id = sa.Column(sa.String(36), sa.ForeignKey("networks.id"),
|
||||
nullable=False)
|
||||
fixed_ips = orm.relationship(IPAllocation, backref='port', lazy='subquery',
|
||||
fixed_ips = orm.relationship(IPAllocation,
|
||||
backref=orm.backref('port',
|
||||
load_on_pending=True),
|
||||
lazy='subquery',
|
||||
cascade='all, delete-orphan',
|
||||
order_by=(IPAllocation.ip_address,
|
||||
IPAllocation.subnet_id))
|
||||
|
@ -26,7 +26,7 @@ class PortSecurityBinding(model_base.BASEV2):
|
||||
# Add a relationship to the Port model in order to be to able to
|
||||
# instruct SQLAlchemy to eagerly load port security binding
|
||||
port = orm.relationship(
|
||||
models_v2.Port,
|
||||
models_v2.Port, load_on_pending=True,
|
||||
backref=orm.backref("port_security", uselist=False,
|
||||
cascade='delete', lazy='joined'))
|
||||
revises_on_change = ('port',)
|
||||
@ -42,7 +42,7 @@ class NetworkSecurityBinding(model_base.BASEV2):
|
||||
# SQLAlchemy to eagerly load default port security setting for ports
|
||||
# on this network
|
||||
network = orm.relationship(
|
||||
models_v2.Network,
|
||||
models_v2.Network, load_on_pending=True,
|
||||
backref=orm.backref("port_security", uselist=False,
|
||||
cascade='delete', lazy='joined'))
|
||||
revises_on_change = ('network',)
|
||||
|
@ -48,7 +48,7 @@ class QosNetworkPolicyBinding(model_base.BASEV2):
|
||||
primary_key=True)
|
||||
revises_on_change = ('network', )
|
||||
network = sa.orm.relationship(
|
||||
models_v2.Network,
|
||||
models_v2.Network, load_on_pending=True,
|
||||
backref=sa.orm.backref("qos_policy_binding", uselist=False,
|
||||
cascade='delete', lazy='joined'))
|
||||
|
||||
@ -68,7 +68,7 @@ class QosPortPolicyBinding(model_base.BASEV2):
|
||||
primary_key=True)
|
||||
revises_on_change = ('port', )
|
||||
port = sa.orm.relationship(
|
||||
models_v2.Port,
|
||||
models_v2.Port, load_on_pending=True,
|
||||
backref=sa.orm.backref("qos_policy_binding", uselist=False,
|
||||
cascade='delete', lazy='joined'))
|
||||
|
||||
@ -83,7 +83,7 @@ class QosBandwidthLimitRule(model_base.HasId, model_base.BASEV2):
|
||||
max_kbps = sa.Column(sa.Integer)
|
||||
max_burst_kbps = sa.Column(sa.Integer)
|
||||
revises_on_change = ('qos_policy', )
|
||||
qos_policy = sa.orm.relationship(QosPolicy)
|
||||
qos_policy = sa.orm.relationship(QosPolicy, load_on_pending=True)
|
||||
|
||||
|
||||
class QosDscpMarkingRule(model_base.HasId, model_base.BASEV2):
|
||||
@ -95,7 +95,7 @@ class QosDscpMarkingRule(model_base.HasId, model_base.BASEV2):
|
||||
unique=True)
|
||||
dscp_mark = sa.Column(sa.Integer)
|
||||
revises_on_change = ('qos_policy', )
|
||||
qos_policy = sa.orm.relationship(QosPolicy)
|
||||
qos_policy = sa.orm.relationship(QosPolicy, load_on_pending=True)
|
||||
|
||||
|
||||
class QosMinimumBandwidthRule(model_base.HasId, model_base.BASEV2):
|
||||
@ -112,7 +112,7 @@ class QosMinimumBandwidthRule(model_base.HasId, model_base.BASEV2):
|
||||
nullable=False,
|
||||
server_default=constants.EGRESS_DIRECTION)
|
||||
revises_on_change = ('qos_policy', )
|
||||
qos_policy = sa.orm.relationship(QosPolicy)
|
||||
qos_policy = sa.orm.relationship(QosPolicy, load_on_pending=True)
|
||||
|
||||
__table_args__ = (
|
||||
sa.UniqueConstraint(
|
||||
|
@ -12,6 +12,7 @@
|
||||
# under the License.
|
||||
|
||||
from oslo_log import log as logging
|
||||
import sqlalchemy
|
||||
from sqlalchemy.orm import exc
|
||||
from sqlalchemy.orm import session as se
|
||||
|
||||
@ -79,33 +80,20 @@ class RevisionPlugin(service_base.ServicePluginBase):
|
||||
resource_res['revision_number'] = resource_db.revision_number
|
||||
|
||||
def _find_related_obj(self, session, obj, relationship_col):
|
||||
"""Find a related object for an object based on relationship column.
|
||||
"""Gets a related object off of a relationship.
|
||||
|
||||
Given a relationship column, find the object that corresponds to it
|
||||
either in the current session or by looking it up if it's not present.
|
||||
Raises a runtime error if the relationship isn't configured correctly
|
||||
for revision bumping.
|
||||
"""
|
||||
# first check to see if it's directly attached to the object already
|
||||
related_obj = getattr(obj, relationship_col)
|
||||
if related_obj:
|
||||
return related_obj
|
||||
rel = getattr(obj.__class__, relationship_col) # get relationship
|
||||
local_rel_col = list(rel.property.local_columns)[0]
|
||||
if len(rel.property.local_columns) > 1:
|
||||
raise RuntimeError(_("Bumping revisions with composite foreign "
|
||||
"keys not supported"))
|
||||
related_model = rel.property.mapper.class_
|
||||
pk = rel.property.mapper.primary_key[0]
|
||||
rel_id = getattr(obj, local_rel_col.name)
|
||||
if not rel_id:
|
||||
return None
|
||||
for session_obj in session:
|
||||
if not isinstance(session_obj, related_model):
|
||||
for rel in sqlalchemy.inspect(obj).mapper.relationships:
|
||||
if rel.key != relationship_col:
|
||||
continue
|
||||
if getattr(session_obj, pk.name) == rel_id:
|
||||
return session_obj
|
||||
# object isn't in session so we have to query for it
|
||||
related_obj = (
|
||||
session.query(related_model).filter(pk == rel_id).
|
||||
first()
|
||||
)
|
||||
return related_obj
|
||||
if not rel.load_on_pending:
|
||||
raise RuntimeError(_("revises_on_change relationships must "
|
||||
"have load_on_pending set to True to "
|
||||
"bump parent revisions on create: %s"),
|
||||
relationship_col)
|
||||
|
Loading…
x
Reference in New Issue
Block a user