Michael Bayer wrote:
> George V. Reilly wrote:
>> I really don't like the
>> isinstance(other_side,
>> sqlalchemy.sql.expression._BindParamClause))
>> in the middle of _check_side. Is there a cleaner way to do this?
>>
>> I found that a combination of
>> * the above _check_side and two-sided visit_binary
>> * doing a better job of declaring ForeignKey relationships in Columns
>> * some explicit primaryjoins in calls to relation()
>> cleaned up all the cases where SA wasn't providing the ids in queries
>>
>> Perhaps the sharding sample in SA 0.6 could be expanded?
check out r0ddd638f1d90 in mercurial. I've added the function from the
example below, plus support for in_op(), to the attribute_shard example.
The old ClauseVisitor method is removed and replaced with this more robust
method.
>
> I think what's needed here is a little more savvy to what the visitors
> package provides. ClauseVisitor provides support for some of the hefty
> transforming objects SQLA has internally in the sql util package, but for
> "finding things" you're much better off using the functional API, which is
> a lot more flexible. Anytime you find yourself using "isinstance()",
> which is in fact sometimes necessary, you can instead try to get the
> visitor dispatch system to give you that type instead. Below I've
> adapted a recipe that is in the beaker example to also include columns and
> operators from binary expressions. We can certainly add this function to
> the sharding example. Ideally the sharding API would come with some
> helper functions, if we could identify some that are of very general use.
>
> from sqlalchemy.sql import visitors
>
> def get_comparisons(query):
>
> binds = {}
> columns = set()
> result = []
> def visit_bindparam(bind):
> value = query._params.get(bind.key, bind.value)
>
> # lazyloader may dig a callable in here, intended
> # to late-evaluate params after autoflush is called.
> # convert to a scalar value.
> if callable(value):
> value = value()
>
> binds[bind] = value
>
> def visit_column(column):
> columns.add(column)
>
> def visit_binary(binary):
> if binary.left in columns and binary.right in binds:
> result.append((binary.left, binary.operator,
> binds[binary.right]))
>
> elif binary.left in binds and binary.right in columns:
> result.append((binary.right, binary.operator,
> binds[binary.left]))
>
> if query._criterion is not None:
> visitors.traverse_depthfirst(query._criterion, {},
> {'bindparam':visit_bindparam,
> 'binary':visit_binary,
> 'column':visit_column
> }
> )
> return result
>
> if __name__ == '__main__':
> from sqlalchemy import *
> from sqlalchemy.orm import *
>
>
> metadata = MetaData()
>
> users = Table('users', metadata,
> Column('id', Integer, primary_key=True, ),
> Column('name', String(30), nullable=False),
> )
>
> addresses = Table('addresses', metadata,
> Column('id', Integer, primary_key=True, ),
> Column('user_id', None, ForeignKey('users.id')),
> Column('email_address', String(50), nullable=False)
> )
>
> class User(object):
> pass
> class Address(object):
> pass
>
> mapper(Address, addresses, properties={
> 'user':relationship(User)
> })
> mapper(User, users)
> sess = create_session()
>
>
> q = sess.query(User).\
> filter(User.id==Address.user_id).\
> filter(User.name=='foo').\
> filter(Address.email_address.like(bindparam('foo'))).\
> params(foo='edward')
>
> for col, op, value in get_comparisons(q):
> print col.name, op, value
>
>
>
>
>
>> --
>> /George V. Reilly, Seattle
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups
>> "sqlalchemy" group.
>> To post to this group, send email to [email protected].
>> To unsubscribe from this group, send email to
>> [email protected].
>> For more options, visit this group at
>> http://groups.google.com/group/sqlalchemy?hl=en.
>>
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/sqlalchemy?hl=en.
>
>
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.