Mysql alchemy filter - python

I am trying to filter a query in mysql alchemy by doing something like this:
query_train = DBSession.query(TokenizedLabel).filter_by(which_disaster!=opts.disaster).all()
But it does not seem to work. Is there a way to filter a query where you are looking for somehting that is not equal to something else -> filter where which_disaster != "irene"
Thanks!

filter_by() cannot handle not equal (!=), use filter() instead:
query_train = DBSession.query(TokenizedLabel).filter(TokenizedLabel.which_disaster!=opts.disaster).all()

Related

SQLAlchemy add condition to query

Beginning of my raw sql statement looks like this:
select if(substr(Table.order_id,1,8)='STRING', Table1.name, t=Table2.type)
Tried to rewrite it in SQLAlchemy query:
query = db_session.query(Table,\
Table1.name if Table.order_id[1:8] == 'STRING' else Table2.type)
But it returned Operator 'getitem' is not supported on this expression.
How can I add this condition to my ORM query without touching models?
Or how can I add raw sql statement in query parameters?
PS: I would prefer not to make any changes to models.
You need to use Functions:
from sqlalchemy import func
q = db_session.query(
func.IF(func.substr(Table.order_id, 1, 8) == 'STRING', Table1.name, Table2.type)
)

Eve SQLAlchemy query catenation

I can do http://127.0.0.1:5000/people?where={"lastname":"like(\"Smi%\")"} to get people.lastname LIKE "Smi%"
How do I concat two conditions, like where city=XX and pop<1000 ?
It's quite simple you just do:
http://127.0.0.1:5000/people?where={"city":"XX", "pop":"<1000"}

How do I do a "starts with" query using SQL alchemy?

I am learning to use SQL alchemy to connect to a mysql database. I want to pull records from the DB that start with a given string. I know that for simple equality all I need to do is this
queryRes = ses.query(Table).filter(Table.fullFilePath == filePath).all()
result = []
How do I do something like this?
queryRes = ses.query(Table).filter(Table.fullFilePath.startsWith(filePath)).all()
result = []
Maybe the query would look like this?
q = ses.query(Table).filter(Table.fullFilePath.like('path%')).all()
SQLAlchemy has a startswith column property, so it works exactly as you'd think:
queryRes = ses.query(Table).filter(Table.fullFilePath.startswith(filePath)).all()
This is the pure SQL:
SELECT * FROM table WHERE field LIKE "string%"
The SQL alchemy is:
q = ses.query(Table).filter(Table.fullFilePath.like('path%')).all()
If you need a case insensitive comparison, use ilike:
session.query(SomeTable).filter(SomeTable.some_column.ilike('bla%')).all()

SQLAlchemy ORM: modify the columns returned from a query

If I've got an SQLAlchemy ORM query:
admin_users = Session.query(User).filter_by(is_admin=True)
Is it possible to modify the columns returned by that query?
For example, so that I could select only the User.id column, and use that in a sub query:
admin_email_addresses = Session.query(EmailAddress)\
.filter(EmailAddress.user_id.in_(admin_users.select_columns(User.id))
Note: the .values() method will not work, as it executes the query and returns an iterable of results (so, ex, EmailAddress.user_id.in_(admin_users.values(User.id)) will perform two queries, not one).
I know that I could modify the first query to be Session.query(User.id), but I'm specifically wondering how I could modify the columns returned by a query.
I feel your pain on the values() thing. In 0.6.5 I added with_entities() which is just like values() except doesn't iterate:
q = q.with_entities(User.id)
Assuming that your Address.user_id defines a ForeignKey, the query below will do the job more efficiently compared to IN operator:
admin_email_addresses = session.query(EmailAddress).\
join(User).filter(User.is_admin==True)
If you do not have a ForeignKey (although you should), you can specify the join condition explicitely:
admin_email_addresses = session.query(EmailAddress).\
join(User, User.id==EmailAddress.user_id).filter(User.is_admin==True)
But if you really would like to do it with in_ operator, here you go (note the subquery):
subq = session.query(User.id).filter(User.is_admin==True).subquery()
admin_email_addresses = session.query(EmailAddress).\
filter(EmailAddress.user_id.in_(subq))

How to deal with "None" DB values in Django queries

I have the following filter query which is doing an SQL OR statement:
results = Stores.objects.filter(Q(title__icontains=prefs.address1) | Q(title__icontains=prefs.address2))
This works fine but if the prefs.address1 and prefs.address2 values (which come from another model) are blank in mySQL, Django complains with the following error:
Cannot use None as a query value
Is there an elegant way to check to see if my filter values are not blank before constructing the OR filter query?
Many thanks.
You could do this which is easily generalisable to more queries
query = Q()
for search in (prefs.address1, prefs.address2):
if search:
query |= Q(title__icontains=search)
results = Stores.objects.filter(query)
This?
thefilter = Q(title__icontains=prefs.address1)
if prefs.address2 is not None:
thefilter = thefilter | Q(title__icontains=prefs.address2)
results = Stores.objects.filter( thefilter)

Categories