openstack team mailing list archive
-
openstack team
-
Mailing list archive
-
Message #05773
Re: Database stuff
2011/11/29 Vishvananda Ishaya <vishvananda@xxxxxxxxx>:
> e) is the right solution imho. The only reason joinedloads slipped in is for efficiency reasons.
>
> In an ideal world the solution would be:
>
> 1) (explicitness) Every object or list of related objects is retrieved with an explicit call:
> instance = db.instance_get(id)
> ifaces = db.interfaces_get_by_instance(id)
> for iface in ifaces:
> ip = db.fixed_ip_get_by_interface(iface['id'])
> 2) (efficiency) Queries are perfectly efficient and all joins that will be used are made at once.
> So the above would be a single db query that joins all instances ifaces and ips.
The way I'd attack these expensive-if-done-one-at-a-time-but-dirt-cheap-
if-done-as-one-big-query is to have a method in the generic layer that
is taylored for this use case. E.g.
def instances_get_all_for_network_with_fixed_ip_addresses():
retval = []
for inst in instance_get_all_by_network():
x = inst.copy()
x['fixed_ip_addresses'] = []
for ip in fixed_ip_get_by_instance(inst['id']):
x['fixed_ip_addresses'].append(ip['address'])
retval.append(x)
return x
And then, in the sqlalchemy driver, I could override that method with
one that issues a query with joinedloads and all the rest of it. The
intent is explicit, drivers that have no speedier way to achieve this
get a free implementation made up of the more primitive methods.
fixed_ip_get_by_instace might also have a default implementation that
issues a fixed_ip_get_all() and then filters the results. This way, a
new driver would be quick to add, and then we could optimize each query
as we move along.
--
Soren Hansen | http://linux2go.dk/
Ubuntu Developer | http://www.ubuntu.com/
OpenStack Developer | http://www.openstack.org/
Follow ups
References