invalid filter: Only one property per query may have inequality filters (>=, <=, >, <)

狂风中的少年 提交于 2019-12-06 04:21:55

It's a bit unclear what you're asking. It's not clear whether you understand the problem: You're trying to use two inequality filters, and it's simply not allowed. Can't do it.

You must work around this datastore limitation.

The most basic option is to brute force it yourself. Use one filter, and manually filter out the results yourself. It may help to filter on begin, and sort on end, but you'll have to go through the results and pick the actual entities you want.

calitem = [x for x in self.appointments.filter("begin >= ", start).filter("begin <= " end) if x.end <= end]

In most cases, you'd want to restructure your data so that you don't need two inequality filters. This may or may not be possible.

I'm trying to guess at what you're doing, but if you're trying to see if someone is busy at 11am based on their calendar, a way to do this is:

  1. Break the day down into time periods instead of using arbitrary time, ie 15min blocks.
  2. Store an event as a list of the time blocks that it uses.
  3. Query for events that contain the time block for 11am.

As I guess you already know, you can't use more than one variable with inequality filters using the datastore. Unless you really need, you can filter using the 'begin' time only, and still get pretty accurate results.

calitem = self.appointments.filter("begin >= ", start).filter("begin <= ", end).fetch(limit=10)

If you really need, using your application logic, you can only show the items that doesn't go beyond the 'end' value. I don't see any other way around.

I have a similar requirement: pick entities out of Datastore that should be rendered/deliverd now. Since Datastore cannot handle this, application logic is required. I make two separate queries for keys that satisfy both ends of the constraint, and then take the intersection of them:

satisfies "begin" criteria: k1, k3, |k4, k5|, k6
                            --------+------+----
satisfies "end" criteria:       k2, |k4, k5|, k7, k8

The intersection of "begin" and "end" are the keys k4, k5.

now = datetime.now()

start_dt_q = FooBar.all()
start_dt_q.filter('start_datetime <', now)
start_dt_q.filter('omit_from_feed =', False)
start_dt_keys = start_dt_q.fetch(None, keys_only=True)

end_dt_q = FooBar.all()
end_dt_q.filter('end_datetime >', now)
end_dt_q.filter('omit_from_feed =', False)
end_dt_keys = end_dt_q.fetch(None, keys_only=True)

# Get "intersection" of two queries; equivalent to
# single query with multiple criteria
valid_dt_keys = list(set(start_dt_keys) & set(end_dt_keys))

I then iterate over those keys getting the entities I need:

for key in valid_dt_keys:
    foobar = FooBar.all().filter('__key__ =', key).get()
    ...

OR:

foobars = FooBar.all().filter('__key__ IN', valid_dt_keys)
for foobar in foobars:
    ...
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!