mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-06-04 23:06:24 -04:00
- restored usage of append_result() extension method for primary
query rows, when the extension is present and only a single- entity result is being returned.
This commit is contained in:
@@ -29,6 +29,10 @@ CHANGES
|
||||
class, not the mapped selectable, as the source of column
|
||||
attributes - so a warning is still issued.
|
||||
|
||||
- restored usage of append_result() extension method for primary
|
||||
query rows, when the extension is present and only a single-
|
||||
entity result is being returned.
|
||||
|
||||
- sql
|
||||
- Added COLLATE support via the .collate(<collation>)
|
||||
expression operator and collate(<expr>, <collation>) sql
|
||||
|
||||
@@ -1442,7 +1442,7 @@ class Mapper(object):
|
||||
|
||||
if 'populate_instance' not in extension.methods or extension.populate_instance(self, context, row, instance, only_load_props=attrs, instancekey=identitykey, isnew=isnew) is EXT_CONTINUE:
|
||||
self.populate_instance(context, instance, row, only_load_props=attrs, instancekey=identitykey, isnew=isnew)
|
||||
|
||||
|
||||
if result is not None and ('append_result' not in extension.methods or extension.append_result(self, context, row, instance, result, instancekey=identitykey, isnew=isnew) is EXT_CONTINUE):
|
||||
result.append(instance)
|
||||
|
||||
|
||||
+24
-11
@@ -954,16 +954,17 @@ class Query(object):
|
||||
|
||||
if getattr(self, '_no_filters', False):
|
||||
filter = None
|
||||
as_instances = False
|
||||
single_entity = custom_rows = False
|
||||
else:
|
||||
as_instances = isinstance(entities[0], _PrimaryMapperEntity) and len(entities) == 1
|
||||
|
||||
if as_instances:
|
||||
single_entity = isinstance(entities[0], _PrimaryMapperEntity) and len(entities) == 1
|
||||
custom_rows = single_entity and 'append_result' in context.extension.methods
|
||||
|
||||
if single_entity:
|
||||
filter = util.OrderedIdentitySet
|
||||
else:
|
||||
filter = util.OrderedSet
|
||||
|
||||
process = [query_entity.row_processor(self, context) for query_entity in entities]
|
||||
process = [query_entity.row_processor(self, context, single_entity) for query_entity in entities]
|
||||
|
||||
while True:
|
||||
context.progress = util.Set()
|
||||
@@ -975,8 +976,12 @@ class Query(object):
|
||||
return
|
||||
else:
|
||||
fetch = cursor.fetchall()
|
||||
|
||||
if as_instances:
|
||||
|
||||
if custom_rows:
|
||||
rows = []
|
||||
for row in fetch:
|
||||
process[0](context, row, rows)
|
||||
elif single_entity:
|
||||
rows = [process[0](context, row) for row in fetch]
|
||||
else:
|
||||
rows = [tuple([proc(context, row) for proc in process]) for row in fetch]
|
||||
@@ -1502,7 +1507,7 @@ class _MapperEntity(_QueryEntity):
|
||||
else:
|
||||
return None
|
||||
|
||||
def row_processor(self, query, context):
|
||||
def row_processor(self, query, context, single_entity):
|
||||
clauses = self._get_entity_clauses(query)
|
||||
if clauses:
|
||||
def proc(context, row):
|
||||
@@ -1524,8 +1529,15 @@ class _MapperEntity(_QueryEntity):
|
||||
class _PrimaryMapperEntity(_MapperEntity):
|
||||
"""entity column corresponding to the 'primary' (first) mapped ORM instance."""
|
||||
|
||||
def row_processor(self, query, context):
|
||||
if context.row_adapter:
|
||||
def row_processor(self, query, context, single_entity):
|
||||
if single_entity and 'append_result' in context.extension.methods:
|
||||
def main(context, row, result):
|
||||
if context.row_adapter:
|
||||
row = context.row_adapter(row)
|
||||
self.mapper._instance(context, row, result,
|
||||
extension=context.extension, only_load_props=context.only_load_props, refresh_instance=context.refresh_instance
|
||||
)
|
||||
elif context.row_adapter:
|
||||
def main(context, row):
|
||||
return self.mapper._instance(context, context.row_adapter(row), None,
|
||||
extension=context.extension, only_load_props=context.only_load_props, refresh_instance=context.refresh_instance
|
||||
@@ -1535,6 +1547,7 @@ class _PrimaryMapperEntity(_MapperEntity):
|
||||
return self.mapper._instance(context, row, None,
|
||||
extension=context.extension, only_load_props=context.only_load_props, refresh_instance=context.refresh_instance
|
||||
)
|
||||
|
||||
return main
|
||||
|
||||
def setup_context(self, query, context):
|
||||
@@ -1608,7 +1621,7 @@ class _ColumnEntity(_QueryEntity):
|
||||
context.attributes[('_ColumnEntity', expr)] = ret = Adapter().traverse(expr, clone=True)
|
||||
return ret
|
||||
|
||||
def row_processor(self, query, context):
|
||||
def row_processor(self, query, context, single_entity):
|
||||
column = self.__resolve_expr_against_query_aliases(query, self.column, context)
|
||||
def proc(context, row):
|
||||
return row[column]
|
||||
|
||||
+11
-6
@@ -1407,8 +1407,10 @@ class MapperExtensionTest(TestBase):
|
||||
sess.flush()
|
||||
sess.delete(u)
|
||||
sess.flush()
|
||||
self.assertEquals(methods, ['before_insert', 'after_insert', 'load', 'translate_row', 'populate_instance', 'get',
|
||||
'translate_row', 'create_instance', 'populate_instance', 'before_update', 'after_update', 'before_delete', 'after_delete'])
|
||||
self.assertEquals(methods,
|
||||
['before_insert', 'after_insert', 'load', 'translate_row', 'populate_instance', 'append_result', 'get', 'translate_row',
|
||||
'create_instance', 'populate_instance', 'append_result', 'before_update', 'after_update', 'before_delete', 'after_delete']
|
||||
)
|
||||
|
||||
def test_inheritance(self):
|
||||
# test using inheritance
|
||||
@@ -1429,8 +1431,9 @@ class MapperExtensionTest(TestBase):
|
||||
sess.flush()
|
||||
sess.delete(am)
|
||||
sess.flush()
|
||||
self.assertEquals(methods, ['before_insert', 'after_insert', 'load', 'translate_row', 'populate_instance', 'get',
|
||||
'translate_row', 'create_instance', 'populate_instance', 'before_update', 'after_update', 'before_delete', 'after_delete'])
|
||||
self.assertEquals(methods,
|
||||
['before_insert', 'after_insert', 'load', 'translate_row', 'populate_instance', 'append_result', 'get',
|
||||
'translate_row', 'create_instance', 'populate_instance', 'append_result', 'before_update', 'after_update', 'before_delete', 'after_delete'])
|
||||
|
||||
def test_after_with_no_changes(self):
|
||||
# test that after_update is called even if no cols were updated
|
||||
@@ -1474,8 +1477,10 @@ class MapperExtensionTest(TestBase):
|
||||
sess.flush()
|
||||
sess.delete(am)
|
||||
sess.flush()
|
||||
self.assertEquals(methods, ['before_insert', 'after_insert', 'load', 'translate_row', 'populate_instance', 'get',
|
||||
'translate_row', 'create_instance', 'populate_instance', 'before_update', 'after_update', 'before_delete', 'after_delete'])
|
||||
self.assertEquals(methods,
|
||||
['before_insert', 'after_insert', 'load', 'translate_row', 'populate_instance', 'append_result', 'get', 'translate_row',
|
||||
'create_instance', 'populate_instance', 'append_result', 'before_update', 'after_update', 'before_delete', 'after_delete']
|
||||
)
|
||||
|
||||
class RequirementsTest(TestBase, AssertsExecutionResults):
|
||||
"""Tests the contract for user classes."""
|
||||
|
||||
Reference in New Issue
Block a user