mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-06-03 06:19:59 -04:00
- adapted gaetan's eager load adaption code for non-mapped column properties
This commit is contained in:
@@ -20,17 +20,13 @@ class ColumnLoader(LoaderStrategy):
|
||||
self.columns = self.parent_property.columns
|
||||
self._should_log_debug = logging.is_debug_enabled(self.logger)
|
||||
|
||||
def setup_query(self, context, eagertable=None, **kwargs):
|
||||
def setup_query(self, context, eagertable=None, parentclauses=None, **kwargs):
|
||||
for c in self.columns:
|
||||
if eagertable is not None:
|
||||
conv = eagertable.corresponding_column(c, raiseerr=False)
|
||||
if conv:
|
||||
context.statement.append_column(conv)
|
||||
else:
|
||||
context.statement.append_column(c)
|
||||
if parentclauses is not None:
|
||||
context.statement.append_column(parentclauses.aliased_column(c))
|
||||
else:
|
||||
context.statement.append_column(c)
|
||||
|
||||
|
||||
def init_class_attribute(self):
|
||||
self.logger.info("register managed attribute %s on class %s" % (self.key, self.parent.class_.__name__))
|
||||
coltype = self.columns[0].type
|
||||
@@ -366,6 +362,7 @@ class EagerLoader(AbstractRelationLoader):
|
||||
self.parent = eagerloader
|
||||
self.target = eagerloader.select_table
|
||||
self.eagertarget = eagerloader.select_table.alias(self._aliashash("/target"))
|
||||
self.extra_cols = {}
|
||||
|
||||
if eagerloader.secondary:
|
||||
self.eagersecondary = eagerloader.secondary.alias(self._aliashash("/secondary"))
|
||||
@@ -392,6 +389,25 @@ class EagerLoader(AbstractRelationLoader):
|
||||
|
||||
self._row_decorator = self._create_decorator_row()
|
||||
|
||||
def aliased_column(self, column):
|
||||
"""return the aliased version of the given column, creating a new label for it if not already
|
||||
present in this AliasedClauses eagertable."""
|
||||
|
||||
conv = self.eagertarget.corresponding_column(column, raiseerr=False)
|
||||
if conv:
|
||||
return conv
|
||||
|
||||
if column in self.extra_cols:
|
||||
return self.extra_cols[column]
|
||||
|
||||
aliased_column = column.copy_container()
|
||||
sql_util.ClauseAdapter(self.eagertarget).traverse(aliased_column)
|
||||
alias = self._aliashash(column.name)
|
||||
aliased_column = aliased_column.label(alias)
|
||||
self._row_decorator.map[column] = alias
|
||||
self.extra_cols[column] = aliased_column
|
||||
return aliased_column
|
||||
|
||||
def _aliashash(self, extra):
|
||||
"""return a deterministic 4 digit hash value for this AliasedClause's id + extra."""
|
||||
# use the first 4 digits of an MD5 hash
|
||||
@@ -423,6 +439,7 @@ class EagerLoader(AbstractRelationLoader):
|
||||
map[parent] = c
|
||||
map[parent._label] = c
|
||||
map[parent.name] = c
|
||||
EagerRowAdapter.map = map
|
||||
return EagerRowAdapter
|
||||
|
||||
def _decorate_row(self, row):
|
||||
|
||||
+16
-10
@@ -455,10 +455,6 @@ class MapperTest(MapperSuperTest):
|
||||
assert str(e) == "Column '%s' is not represented in mapper's table. Use the `column_property()` function to force this column to be mapped as a read-only attribute." % str(f)
|
||||
clear_mappers()
|
||||
|
||||
mapper(Address, addresses, properties={
|
||||
'user':relation(User, lazy=False)
|
||||
})
|
||||
|
||||
mapper(User, users, properties={
|
||||
'concat': column_property(f),
|
||||
'count': column_property(select([func.count(addresses.c.address_id)], users.c.user_id==addresses.c.user_id, scalar=True).label('count'))
|
||||
@@ -473,12 +469,22 @@ class MapperTest(MapperSuperTest):
|
||||
|
||||
### eager loads, not really working across all DBs, no column aliasing in place so
|
||||
# results still wont be good for larger situations
|
||||
#l = sess.query(Address).select()
|
||||
l = sess.query(Address).options(lazyload('user')).select()
|
||||
for a in l:
|
||||
print "User", a.user.user_id, a.user.user_name, a.user.concat, a.user.count
|
||||
assert l[0].user.concat == l[0].user.user_id * 2 == 14
|
||||
assert l[1].user.concat == l[1].user.user_id * 2 == 16
|
||||
clear_mappers()
|
||||
mapper(Address, addresses, properties={
|
||||
'user':relation(User, lazy=False)
|
||||
})
|
||||
|
||||
mapper(User, users, properties={
|
||||
'concat': column_property(f),
|
||||
})
|
||||
|
||||
for x in range(0, 2):
|
||||
sess.clear()
|
||||
l = sess.query(Address).select()
|
||||
for a in l:
|
||||
print "User", a.user.user_id, a.user.user_name, a.user.concat
|
||||
assert l[0].user.concat == l[0].user.user_id * 2 == 14
|
||||
assert l[1].user.concat == l[1].user.user_id * 2 == 16
|
||||
|
||||
|
||||
@testbase.unsupported('firebird')
|
||||
|
||||
Reference in New Issue
Block a user