Re: [Sqlalchemy-tickets] [sqlalchemy] #2824: Add ability to query column sets as one entity
Brought to you by:
zzzeek
|
From: sqlalchemy <mi...@zz...> - 2013-10-03 13:39:25
|
#2824: Add ability to query column sets as one entity
------------------------------+-------------------------------
Reporter: vmagamedov | Owner: zzzeek
Type: enhancement | Status: new
Priority: high | Milestone: 0.9.0
Component: orm | Severity: major - 1-3 hours
Resolution: | Keywords:
Progress State: in progress |
------------------------------+-------------------------------
Comment (by vmagamedov):
I'm published my library on !GitHub:
https://github.com/vmagamedov/sqlconstruct - it is not
finished/polished/documented yet, but I'm already wrote some tests and
they can help.
Here is my Bundle subclass:
{{{#!python
class Construct(Bundle):
def __init__(self, spec):
self._spec = OrderedDict(spec)
self._columns = tuple(set(chain(*map(_yield_columns,
spec.values()))))
super(Construct, self).__init__(None, *self._columns)
def from_row(self, row):
values_map = dict(zip(self._columns, row))
get_value = partial(_get_value_from_map, values_map)
return Object(zip(
self._spec.keys(),
map(get_value, self._spec.values()),
))
def create_row_processor(self, query, procs, labels):
def proc(row, result):
return self.from_row([proc(row, None) for proc in procs])
return proc
}}}
Some errors which are speaks for themselves:
{{{
======================================================================
ERROR: test_query_count (test_sqlconstruct.TestConstruct)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/vm/ws/sqlconstruct/test_sqlconstruct.py", line 336, in
test_query_count
self.assertEqual(query.count(), 2)
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 2539, in count
return self.from_self(col).scalar()
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 952, in from_self
q = self._from_selectable(fromclause)
File "<string>", line 1, in <lambda>
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 53, in generate
fn(self, *args[1:], **kw)
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 981, in _from_selectable
e.adapt_to_selectable(self, self._from_obj[0])
AttributeError: '_BundleEntity' object has no attribute
'adapt_to_selectable'
======================================================================
ERROR: test_query_with_explicit_join (test_sqlconstruct.TestConstruct)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/vm/ws/sqlconstruct/test_sqlconstruct.py", line 444, in
test_query_with_explicit_join
.join(self.b_cls.a)
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 1673, in join
from_joinpoint=from_joinpoint)
File "<string>", line 1, in <lambda>
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 53, in generate
fn(self, *args[1:], **kw)
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 1806, in _join
outerjoin, create_aliases, prop)
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 1854, in _join_left_to_right
self._join_to_left(l_info, left, right, onclause, outerjoin)
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 1967, in _join_to_left
if ent.corresponds_to(left):
AttributeError: '_BundleEntity' object has no attribute 'corresponds_to'
======================================================================
ERROR: test_query_with_implicit_join_ge_08
(test_sqlconstruct.TestConstruct)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/vm/ws/sqlconstruct/test_sqlconstruct.py", line 503, in
test_query_with_implicit_join_ge_08
.join(self.a_cls)
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 1673, in join
from_joinpoint=from_joinpoint)
File "<string>", line 1, in <lambda>
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 53, in generate
fn(self, *args[1:], **kw)
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 1806, in _join
outerjoin, create_aliases, prop)
File
"/Users/vm/ws/sqlconstruct/.tox/py27sqla0X/src/sqlalchemy/lib/sqlalchemy/orm/query.py",
line 1819, in _join_left_to_right
left = self._entities[0].entity_zero_or_selectable
AttributeError: '_BundleEntity' object has no attribute
'entity_zero_or_selectable'
}}}
Other tests failed because bundles can't be selected as "single entity". I
think that bundles can work like models: when you querying only one
bundle, query should yield bundles and not keyed tuples with one bundle.
Here is my custom entity wrapper with some hacks to fix tests (very
specific, supports only Construct entities for simplicity):
{{{#!python
class _ConstructEntity(_QueryEntity):
"""Queryable construct entities
Adapted from: http://www.sqlalchemy.org/trac/ticket/2824
"""
filter_fn = id
entities = ()
entity_zero_or_selectable = None
# hack for sqlalchemy.orm.query:Query class
class mapper:
class dispatch:
append_result = False
def __init__(self, query, struct):
query._entities.append(self)
self.struct = struct
def corresponds_to(self, entity):
return False
def adapt_to_selectable(self, query, sel):
query._entities.append(self)
#def setup_entity(self, *args, **kwargs):
# raise NotImplementedError
def setup_context(self, query, context):
context.primary_columns.extend(self.struct.columns)
def row_processor(self, query, context, custom_rows):
def processor(row, result):
struct_row = [row[c] for c in self.struct.columns]
return self.struct.from_row(struct_row)
return processor, None
}}}
--
Ticket URL: <http://www.sqlalchemy.org/trac/ticket/2824#comment:10>
sqlalchemy <http://www.sqlalchemy.org/>
The Database Toolkit for Python
|