Andru
Andru

Reputation: 260

Does sqlalchemy have a filter object like Q in django?

How to rewrite this code which used django orm on sqlalchemy orm?

list_of_filters = [Q(active=True)]

if self.proxy_anonymity:
    list_of_filters.append(Q(anonymity=True))

if self.proxy_https:
    list_of_filters.append(Q(https=True))

if hasattr(spider, 'bad_proxies') and spider.bad_proxies:
    list_of_filters.append(~Q(ip__in=spider.bad_proxies))

proxy_filter = reduce(operator.and_, list_of_filters)

return proxy_filter

Upvotes: 3

Views: 2512

Answers (1)

Ilja Everilä
Ilja Everilä

Reputation: 52929

SQLAlchemy uses a different approach by providing instrumented attributes on mapped classes, as explained in "Declare a Mapping":

When our class is constructed, Declarative replaces all the Column objects with special Python accessors known as descriptors; this is a process known as instrumentation.

You can then use those attributes to form predicate expressions etc. using what is called the SQL Expression Language.

There are some similarities when forming the actual expressions, such as using the bitwise operators |, &, and ~ as OR, AND, and NOT respectively. Alternatively SQLAlchemy provides the constructs or_(), and_(), and not_(). All in all you should read "Querying" in the ORM tutorial.

So if your model class was for example Proxy, your code could look like

# Note that it is redundant to compare a boolean column with a boolean value.
# Just use the value of the column itself.
list_of_filters = [Proxy.active]

if self.proxy_anonymity:
    # Again, use a boolean column as is.
    list_of_filters.append(Proxy.anonymity)

if self.proxy_https:
    list_of_filters.append(Proxy.https)

if hasattr(spider, 'bad_proxies') and spider.bad_proxies:
    list_of_filters.append(Proxy.ip.in_(spider.bad_proxies))

proxy_filter = and_(*list_of_filters)

return proxy_filter

Upvotes: 2

Related Questions