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"}
Related
I have a table that stores tasks submitted by users, with timestamps. I would like to write a query that returns certain rows based on when they were submitted (was it this day/week/month..).
To check if it was submitted on this week, I wanted to use date.isocalendar()[1] function. The problem is, that my timestamps are datetimes, so I would need to transform those to dates.
Using func:
filter(func.date(Task.timestamp) == datetime.date(datetime.utcnow()))
works properly.
But I need the date object's isocalendar() method, so I try
filter(func.date(Task.timestamp).isocalendar()[1]==datetime.date(datetime.utcnow()).isocalendar()[1])
and it's no good, I get AttributeError: Neither 'Function' object nor 'Comparator' object has an attribute 'isocalendar'
If I make a simple query and try datetime.date(task.timestamp).isocalendar()[1] it works properly.
How do I get it to work in the query's filter?
Rule of thumb when understanding and debugging sqlalchemy queries is to always think – "How will it look in SQL?"
isocalendar() is a python function, and sqlalchemy query filters get compiled to SQL. Moreover, isocalendar() returns a tuple – and while rendering tuple comparison as SQL is probably possible, it's more trouble then it's worth. You should compare scalars and find sql date functions that suit you.
It seems you're looking to compare week number, so something like this should do the trick:
filter(func.week(Task.timestamp)==datetime.utcnow().isocalendar()[1])
Can you try sqlalchemy.extract(func.date('year', Task.timestamp)) == ... ?
You cannot mix pure python functions with those which are executed on the SQL backend. From your code it looks like you are trying to filter on the iso week. One way to do it would be to load everything from the database into memory and perform the filtering there. Obviously, it most cases it is far from efficient.
An alternative would be to use respective SQL functions, which sqlalchemy will call for you. On MySQL it looks like the function you need is weekofyear, so your filter might look similar to below:
_utcnow = datetime.utcnow().date()
_isoweek = _utcnow.isocalendar()[1]
q = db.session.query(...)
# ...
q = q.filter(db.func.weekofyear(Task.timestamp) == _isoweek)
I'm currently querying a MongoDB with the following mongoengine query:
queryResults = Event.objects(title__icontains=q)
This works well, but I want to add another argument so it becomes something like this:
queryResults = Event.objects(title__icontains=q and end__gte=datetime.utcnow())
Unfortunately, simply using and doesn't work here. I tried other things like & and &&, but to no avail. I also checked the mongoengine docs, but I can't find anything about it.
Would anybody have any idea how I could do this? All tips are welcome!
Try putting a "," between this:
queryResults = Event.objects(title__icontains=q, end__gte=datetime.utcnow())
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()
I need to get the last X rows from a table, but in order of the ID. How could I achieve this?
query = users.select().order_by(users.c.id.desc()).limit(5)
print reversed(conn.execute(query).fetchall() )
something like that anyway
This worked for me...
c=session.query(a).order_by(a.id.desc()).limit(2)
c=c[::-1]
This solution is 10 times faster than the python slicing solution proposed by BrendanSimon.
I believe you can prefix the order_by parameter with a '-' to get reverse order.
query = users.select().order_by(-users.c.id.desc()).limit(5)
Also, I believe you can use python slices as an alternative to limit.
query = users.select().order_by(users.c.id.desc())[-5:]
query = users.select().order_by(-users.c.id.desc())[:5]
Consider this query:
query = Novel.objects.< ...some filtering... >.annotate(
latest_chapter_id=Max("volume__chapter__id")
)
Actually what I need is to annotate each Novel with its latest Chapter object, so after this query, I have to execute another query to select actual objects by annotated IDs. IMO this is ugly. Is there a way to combine them into a single query?
Yes, it's possible.
To get a queryset containing all Chapters which are the last in their Novels, simply do:
from django.db.models.expressions import F
from django.db.models.aggregates import Max
Chapters.objects.annotate(last_chapter_pk=Max('novel__chapter__pk')
).filter(pk=F('last_chapter_pk'))
Tested on Django 1.7.
Possible with Django 3.2+
Make use of django.db.models.functions.JSONObject (added in Django 3.2) to combine multiple fields (in this example, I'm fetching the latest object, however it is possible to fetch any arbitrary object provided that you can get LIMIT 1) to yield your object):
MainModel.objects.annotate(
last_object=RelatedModel.objects.filter(mainmodel=OuterRef("pk"))
.order_by("-date_created")
.values(
data=JSONObject(
id="id", body="body", date_created="date_created"
)
)[:1]
)
Yes, using Subqueries, docs: https://docs.djangoproject.com/en/3.0/ref/models/expressions/#subquery-expressions
latest_chapters = Chapter.objects.filter(novel = OuterRef("pk"))\
.order_by("chapter_order")
novels_with_chapter = Novel.objects.annotate(
latest_chapter = Subquery(latest_chapters.values("chapter")[:1]))
Tested on Django 3.0
The subquery creates a select statement inside the select statement for the novels, then adds this as an annotation. This means you only hit the database once.
I also prefer this to Rune's answer as it actually annotates a Novel object.
Hope this helps, anyone who came looking like much later like I did.
No, it's not possible to combine them into a single query.
You can read the following blog post to find two workarounds.