我想动态地在sqlalchemy查询对象中获取paramer的值:
q = session.query(Model).filter(Model.foo = 6)
Run Code Online (Sandbox Code Playgroud)
我现在希望能够从q中检索值6
assert(q.magic == 6)
Run Code Online (Sandbox Code Playgroud)
尝试:打印q._criterion# - > models.foo =:foo_1但是foo_1的值在哪里?
Mar*_*ams 12
SQLAlchemy从过滤器谓词生成树结构,根据需要附加每个叶子并将结果放入Query._criterion.您可以使用get_children()各种类ClauseElement和ColumnElement类的方法来探索它.
因为Model.foo == 6你最终得到这样的东西:
Model.foo == 6
|
_BinaryExpression
/ \
/ \
/ \
Column('foo', Integer(), _BindParamClause(u'%(168261004 foo)s',
...) 6, type_=Integer())
Run Code Online (Sandbox Code Playgroud)
如果你和两个谓词一样,(Model.foo == 6) & (Model.name == 'a name')或者通过链接filter来电,你会得到一个BooleanClauseList有两个_BinaryExpression孩子的人.这意味着您无法对简单表达式进行硬编码以可靠地返回所需的值,而是必须遍历谓词树.
在traverse从功能sqlalchemy.sql.visitors做到了这一点,靠的是涉及每个元素的特殊名字的字典__visit_name__属性的处理功能.这是一个广度优先的遍历,如您所见,适用于下面的示例; 还有深度优先版本.
以下函数显示如何从给定查询生成列参数对列表.我从Beaker缓存示例中对其进行了调整:
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')]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
857 次 |
| 最近记录: |