【发布时间】:2011-03-21 06:26:04
【问题描述】:
我有一个包含 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/recipe/custom-model-properties-are-cute/
我正在尝试向我的模型添加一个自定义字段,如下所示:
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,但这似乎没有帮助。绝望地陷入困境还是朝着正确的方向前进?
【问题讨论】:
标签: google-app-engine google-cloud-datastore gql