django重写model的save方法实现同时写2个数据库

最近有个需求就是当执行save时需要把数据写入2个数据库,查看文档后发现直接重写save方法比较简单。

首先建立2个测试数据库testa和testb,然后在settings中配置数据库:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testa',
        'USER': 'root',
        'PASSWORD': 'asdasd',
        'HOST': '192.168.0.17',
    },
    'testdb': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'testb',
        'USER': 'root',
        'PASSWORD': 'asdasd',
        'HOST': '192.168.0.18',
    },
}

接下来定义model:

from django.db import models
# Create your models here.
class ABCD(models.Model):
    name = models.CharField(max_length=200, unique=False)
    def __unicode__(self):
        return "%s" % (self.name)
    def save(self, *args, **kwargs):
        print "save testa"
        super(ABCD, self).save(*args, **kwargs)
        print "save testb"
        super(ABCD, self).save(using="testdb", *args, **kwargs)

注意最后一行的using指定了写入哪个库中,接下来执行syncdb命令创建表,这里只会在default中创建,所以我们手动在testdb中创建表。

然后进入shell中测试一下:

% python manage.py shell
Python 2.7.8 (default, Nov 10 2014, 08:19:18)
Type "copyright", "credits" or "license" for more information.
IPython 2.3.0 -- An enhanced Interactive Python.
?         -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help      -> Python's own help system.
object?   -> Details about 'object', use 'object??' for extra details.
In [1]: from abcd.models import ABCD
In [2]: c = ABCD(name="testc")
In [3]: c.save()
save testa
save testb

再看数据库中,插入都成功了。这里可能产生的问题就是大量并发请求时造成主键的不一致,但对于写操作不频繁的情况下也是一种可以接受的选择。