我希望得到一个paramer的动态一SQLAlchemy的查询对象的值:SQLAlchemy的绑定值
q = session.query(Model).filter(Model.foo = 6)
我现在希望能够从q个
assert(q.magic == 6)
尝试retrive值6 : print q._criterion# - > models.foo =:foo_1 但foo_1的值在哪里?
我希望得到一个paramer的动态一SQLAlchemy的查询对象的值:SQLAlchemy的绑定值
q = session.query(Model).filter(Model.foo = 6)
我现在希望能够从q个
assert(q.magic == 6)
尝试retrive值6 : print q._criterion# - > models.foo =:foo_1 但foo_1的值在哪里?
SQLAlchemy从您的过滤器谓词中生成树结构,并根据需要附加每个叶,并将结果放入Query._criterion
。您可以使用各种ClauseElement
和ColumnElement
类的get_children()
方法来探索此方法。
为Model.foo == 6
你最终的东西是这样的:
Model.foo == 6
|
_BinaryExpression
/\
/ \
/ \
Column('foo', Integer(), _BindParamClause(u'%(168261004 foo)s',
...) 6, type_=Integer())
如果你要&在一起的两个谓词,像(Model.foo == 6) & (Model.name == 'a name')
或通过链接filter
电话,你会得到一个BooleanClauseList
有两个孩子_BinaryExpression
。这意味着你不能硬编码一个简单的表达式来可靠地返回你想要的值,而是必须遍历谓词树。
sqlalchemy.sql.visitors
的traverse
函数就是这样做的,它依赖于将每个元素的__visit_name__
属性与处理函数相关联的特殊名称字典。这是一个宽度优先的遍历,正如你可以看到的,它适用于下面的例子。还有一个深度优先版本可用。
以下函数显示如何从给定查询生成列参数对的列表。我改编自the Beaker caching example:
def extract_cols_params(query):
if query._criterion is None:
return []
c, v = [], []
def visit_bindparam(bind):
value = query._params.get(bind.key, bind.value)
if callable(value):
value = value()
v.append(value)
def visit_column(col):
c.append('%s.%s' % (col.table.name, col.name))
visitors.traverse(query._criterion, # our predicate tree
{}, # kwargs for the iterator used by
# the traversal; undeeded.
{'bindparam': visit_bindparam, # for _BindParamClauses
'column' : visit_column}) # for Columns
return zip(c, v)
>>> extract_cols_params(Session.query(Model).filter((Model.foo == 6)
).filter(Model.name == 'a name'))
[('models.foo', 6), ('models.name', 'a name')]