DjangoのMasterSlaveRouterの話し(稲川淳二風)

これは最近Djangoを使い始めた人の話しなんですけどね。Djangoは複数DBが扱えるんですよ。ええ。それでMaster/Slaveなレプリケーションを扱いたいなーなんて思ってたんです。

ところがね。ドキュメントに書いてあるMasterSlaveRouterを使った時に不思議な現象に遭遇しちゃったんですよ。

https://docs.djangoproject.com/en/dev/topics/db/multi-db/

ドキュメントに書いてあるとおり「MasterSlaveRouter」を実装しておそるおそるsyncdbして、そーと見たら、フッと出た。出たんですよ!エラー

$ python manage.py syncdb
 .
 .
 django.db.utils.IntegrityError: (1062, "Duplicate entry 'contenttypes-contenttype' for key 'app_label'")

あれー。おかしいなー。おかしいなー。 なんどsyncdbし直してもずーと出るなー。てしばらく怖くて動けなかったんですよ。

このままじゃいけないなー。なんとかしなくちゃなー。て強く念じたら、なんとか動けるようになって、例の先生に頼ったら、出て来たんですよ。下記のURLが。

http://stackoverflow.com/questions/10497418/django-syncdb-trying-to-insert-duplicate-rows-when-multiple-databases-are-specif

どうやら、この現象は、djangoがデフォルト作るモデルの中に、独自のキャッシュ機構を備えた、Managerオブジェクトを使ってるっていうが原因ぽいなーてのが分かったんですよ。そう曰く付きだったんですよ。怖いなー怖いなー。

お祓いの方法も書いてあって、MasterSlaveRouterのdb_for_readで、そういった独自のキャッシュ機構を持ってる奴らは、必ずMasterを見る様にしてやれば、その現象は収まるらしいんですよー。

  def db_for_read(self, model, **hints):
        if model._meta.app_label in ('contenttypes', 'sites'):
            return 'master'
        else:
            return 'slave' 


いやー。これで安心して眠れるなーて、胸を撫で下ろしたんですけど、よく考えるとこれって微妙なお祓いの仕方だなーて思って、ゾッとしました。

なんか他に良い方法ないのかなーって今でもその人は夜な夜な探してるらしいですよ。。

。。。なんだよこれ。