Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>SQLAlchemy generates a tree structure from your filter predicates, appending each leaf on as appropriate and putting the result in <code>Query._criterion</code>. You can explore this with the <code>get_children()</code> method of various <code>ClauseElement</code> and <code>ColumnElement</code> classes. </p> <p>For <code>Model.foo == 6</code> you'll end up with something like this:</p> <pre><code> Model.foo == 6 | _BinaryExpression / \ / \ / \ Column('foo', Integer(), _BindParamClause(u'%(168261004 foo)s', ...) 6, type_=Integer()) </code></pre> <p>If you were to &amp; together two predicates, like <code>(Model.foo == 6) &amp; (Model.name == 'a name')</code> or by chaining <code>filter</code> calls, you'd get a <code>BooleanClauseList</code> with two <code>_BinaryExpression</code> children. This means you can't hard code a simple expression to reliably return the values you want but instead have to traverse the predicate tree.</p> <p>The <code>traverse</code> function from <code>sqlalchemy.sql.visitors</code> does just that, relying on a dictionary of special names that relate each Element's <code>__visit_name__</code> attribute to a processing function. This is a breadth-first traversal, which as you can see is appropriate for the example below; there's also a depth-first version available.</p> <p>The following function shows how to generate a list of column-parameter pairs from a given query. I adapted it from <a href="http://hg.sqlalchemy.org/sqlalchemy/file/b1573376f29c/examples/beaker_caching/caching_query.py#l248)" rel="noreferrer">the Beaker caching example</a>:</p> <pre><code> 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) &gt;&gt;&gt; extract_cols_params(Session.query(Model).filter((Model.foo == 6) ).filter(Model.name == 'a name')) [('models.foo', 6), ('models.name', 'a name')] </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload