次のような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は1つのプロパティでのみ不等式フィルターを許可し、BETWEEN
構文をサポートしていません。これを回避して、App Engineでこれらと同等のクエリを作成するにはどうすればよいですか?
また、ListProperty
「ライブ」にすることもできますか、それともレコードの作成時に計算する必要がありますか?
解決策の最初の刺し傷で更新された質問:
したがって、以下のDavidの回答と次のような記事に基づいています。
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
たが、それは役に立たないようです。うまくいけないのか、正しい方向に向かっていますか?