rediscoを使ってみた

rediscoって何?

redisco とは RedisDjango モデルっぽく使えるようにしてくれるライブラリ。
redis-py に依存している。
今回MySQLのTPSだと問題になりそうな処理がある & その処理にある程度複雑なモデルが必要だったので @ に教えてもらって使ってみた。

使い方

  • 接続
import redisco
redisco.connection_setup(host='localhost', port=6380, db=10)

保存や取得をする前には接続する必要がある。connection_setup を呼ぶことで redis との接続を作って保持してくれる。

  • モデル定義
from redisco import models
class AnimalType(models.Model):
    name = models.Attribute(required=True)

class Animal(models.Model):
    name = models.Attribute(required=True, indexed=False)
    animal_type = models. ReferenceField(AnimalType, required=True)
    created_at = models.DateTimeField(auto_now_add=True)
    coord_x = models.IntegerField(equired=True, indexed=False)
    coord_y = models.IntegerField(equired=True, indexed=False)

こんな感じでモデルを作れる。
Django と比べると
CharField -> Attribute
ForienKey -> ReferenceField
になってるのが主な違い。

  • 保存
cat = Animal.objects.create(name=u'ネコ')
animal = Animal()
animal.name = u'タマ'
animal.type = cat
animal.coord_x = 1
animal.coord_y = 1
animal.save()

オブジェクトを作って保存する方法は Djangoモデルと同じ。
保存時に Django と同じように id を作ってくれる。
ただし id が int じゃなく数値文字列('10'とか)なので注意。

  • 取得

普通に取って来るだけなら(遅延評価してるとこも含めて) Django と変わらない。(get はないっぽいけど)

cats_query = AnimalType.objects.filter(name=u'ネコ')

cats = cats_query.members
# これも同じ
cats = list(cats_query)

cats_count = len(cats_query)

cat = cats_query.first()
# これも同じ
cat = cats_query[0]


ただ、indexd=False なフィールドを条件に指定することは出来ない。デフォルトが index=True なので、絶対に条件に指定しないフィールド以外は index=False にしないこと推奨。

# これはOKだけど
animal = Animal.objects.filter(animal_type=cat)[0]
# これはエラー
tama = Animal.objects.filter(name=u'タマ')[0]


また、filter() では id を条件に指定することは出来ないので、id で引きたい場合は、get_by_id() を使う。

# これはエラーなので
animal = Animal.objects.filter(id=1)[0]
# こっちを使う
# tama.id は str だけど、ここに指定するのは int でOK
tama = Animal.objects.get_by_id(1)


Djangoみたいに __in とか __lte とかも使える。その場合は filter() の代わりに zfilter() を使う。ただ、zfilter() だと list() で評価は出来ないし、複数の条件も指定出来ない。

# これは出来るけど
animals_query = Animal.objects.zfilter(created_at__lte=datetime.datetime.now())
# これは出来ない
cats_query = Animal.objects.zfilter(created_at__lte=datetime.datetime.now(), animal_type=cat)

# これは出来るけど
animals = animals_query.member
animals.count = len(animals_query.member)
animal = animals_query.member[0]
# これは出来ない
animals = list(animals_query)
animals = len(animals_query)
animal = animals_query[0]


使ってみた感想
redisco を使うと、保存時に自動的にトランザクションを使ってくれるし key を自分で考えたりせずに使えるので非常に楽だった。
ただしDjangoモデルとは微妙に違うし、ドキュメント少ない上に日本語のものは皆無なのでソースを追ったりする必要があったのが面倒。
今回は使ってないけど、Djangoモデルっぽいもの以外に Set とかも作れるので単純な Key-Value の用途以外で使う場合は検討してみる価値が十分にあると思う。