У меня есть модель, содержащая диапазоны IP-адресов, подобные этой:
class Country(db.Model):
begin_ipnum = db.IntegerProperty()
end_ipnum = db.IntegerProperty()
В базе данных SQL я смог бы найти строки, которые содержали IP в определенном диапазоне, например:
SELECT * FROM Country WHERE ipnum BETWEEN begin_ipnum AND end_ipnum
или это:
SELECT * FROM Country WHERE begin_ipnum < ipnum AND end_ipnum > ipnum
К сожалению, GQL разрешает фильтры неравенства только для одного свойства и не поддерживает синтаксис BETWEEN
. Как я могу обойти это и построить эквивалентный запрос в App Engine?
Кроме того, может ли ListProperty
быть «живым» или его нужно вычислять при создании записи?
вопрос дополнен первым ударом по решению:
Итак, основываясь на ответе Дэвида ниже и таких статьях:
http://appengine -cookbook.appspot.com / рецепт / заказ модели-свойства-это мило /
Я пытаюсь добавить настраиваемое поле в мою модель, например:
class IpRangeProperty(db.Property):
def __init__(self, begin=None, end=None, **kwargs):
if not isinstance(begin, db.IntegerProperty) or not isinstance(end, db.IntegerProperty):
raise TypeError('Begin and End must be Integers.')
self.begin = begin
self.end = end
super(IpRangeProperty, self).__init__(self.begin, self.end, **kwargs)
def get_value_for_datastore(self, model_instance):
begin = self.begin.get_value_for_datastore(model_instance)
end = self.end.get_value_for_datastore(model_instance)
if begin is not None and end is not None:
return range(begin, end)
class Country(db.Model):
begin_ipnum = db.IntegerProperty()
end_ipnum = db.IntegerProperty()
ip_range = IpRangeProperty(begin=begin_ipnum, end=end_ipnum)
Мышление заключается в том, что после добавления пользовательского свойства я могу просто импортировать свой набор данных как есть, а затем выполнить запросы на основе ListProperty следующим образом:
q = Country.gql('WHERE ip_range = :1', my_num_ipaddress)
Когда я пытаюсь вставить новые объекты Country, это терпит неудачу, упуская из виду невозможность создать имя:
...
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/db/__init__.py", line 619, in _attr_name
return '_' + self.name
TypeError: cannot concatenate 'str' and 'IntegerProperty' objects
Я попытался определить метод attr_name
для нового свойства или просто установить self.name
, но это, похоже, не помогает. Безнадежно застрял или движется в правильном направлении?