使用数据库路由器在Django应用之间共享(mysql)数据库 [英] Sharing (mysql) database between apps Django with Database routers

查看:109
本文介绍了使用数据库路由器在Django应用之间共享(mysql)数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个django项目,然后创建了两个应用程序app1和app2.我希望这两个应用程序共享一个mysql数据库('mysql的'nameofDB'到django的'mydb').我将数据库添加到settings.py中的DATABASES中,并为每个应用程序创建了一个dbrouter文件,并将每个路由器都添加至DATABASE_ROUTERS.同样在settings.py中,将每个应用添加到INSTALLED_APPS.

I've created a django project and then two apps, app1 and app2. I want that both apps share a mysql database('nameofDB' to mysql, 'mydb' to django). I added the database to DATABASES in settings.py and for each app I created a dbrouter file, and added each router to DATABASE_ROUTERS. Also in settings.py added each app to INSTALLED_APPS.

我的问题是当我尝试制作

My problem is when I try to make

python manage.py syncdb --database=mydb

因为它不同步两个应用程序(仅同步app1).它说:

Because it doesn't sync both apps(only app1). It says:

Creating tables ...
Creating table app1_model1
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)

这是我的设置.py:

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app1',
    'app2',
)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
    'mydb':{
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'nameofDB',
        'USER':'username',
        'PASSWORD':'password',
    }
}

DATABASE_ROUTERS = ['app1.dbRouter.App1DBRouter', 'app2.dbRouter.App2DBRouter']

这是我的模特:

app1/models.py:

app1/models.py:

class Model1(models.Model):
    name = models.CharField(max_length=100)

app2/models.py:

app2/models.py:

class Model2(models.Model):
    name = models.CharField(max_length=100)

这是我的弟兄们

app1/dbRouter.py

app1/dbRouter.py

class App1DBRouter(object):
    def db_for_read(self,model, **hints):
        if model._meta.app_label == 'app1':
            return 'mydb'
        return None
    def db_for_write(self,model, **hints):
        if model._meta.app_label == 'app1':
            return 'mydb'
        return None
    def allow_relation(self,obj1, obj2, **hints):
        if obj1._meta.app_label == 'app1' and \
           obj2._meta.app_label == 'app1':
           return True
        return None
    def allow_syncdb(self,db, model):
        if db == 'mydb':
            return model._meta.app_label == 'app1'
        elif model._meta.app_label == 'app1':
            return False
        return None

app2/dbRouter.py

app2/dbRouter.py

class App2DBRouter(object):
    def db_for_read(self,model, **hints):
        if model._meta.app_label == 'app2':
            return 'mydb'
        return None
    def db_for_write(self,model, **hints):
        if model._meta.app_label == 'app2':
            return 'mydb'
        return None
    def allow_relation(self,obj1, obj2, **hints):
        if obj1._meta.app_label == 'app2' and \
           obj2._meta.app_label == 'app2':
           return True
        return None
    def allow_syncdb(self,db, model):
        if db == 'mydb':
            return model._meta.app_label == 'app2'
        elif model._meta.app_label == 'app2':
            return False
        return None

这有什么问题?我应该怎么办?提前致谢!:)

What's wrong with it? What should I do? Thanks in advance! :)

推荐答案

我同意Daniel Roseman的观点.如果您有两个或两个以上使用同一个数据库的应用程序,那么使用一台路由器就可以了.一般来说,每个非默认数据库可能有一个路由器?

I agree with Daniel Roseman. When you have two or more apps using the same db than you migth be fine with one router. In general perhaps one router per each non default database?

但是,如果您确实需要两个路由器,那么这里是一个解决方案.

But if you really need two routers here is a solution.

只要allow_syncdb返回None,Django根db路由器就会尝试从DATABASE_ROUTERS获得所有路由器.因此,App1DBRouter.allow_syncdb需要为model._meta.app_label =='app2'和db =='mydb'返回None(而不是False).这样App2DBRouter.allow_syncdb将有机会被调用.

The Django root db router tries all routers from DATABASE_ROUTERS as long as allow_syncdb returns None. Thus App1DBRouter.allow_syncdb needs to return None (instead of False) for model._meta.app_label == 'app2' and db == 'mydb'. This way App2DBRouter.allow_syncdb will have a chance to be called.

我让您的syncdb可以进行以下更改

I got your syncdb working with following changes

class App1DBRouter(object):
    ...
    def allow_syncdb(self,db, model):
        if db == 'mydb':
            if model._meta.app_label == 'app1':
                return True
        elif model._meta.app_label == 'app1':
            return False
        return None

class App2DBRouter(object):
    ...
    def allow_syncdb(self,db, model):
        if db == 'mydb':
            if model._meta.app_label == 'app2':
                return True
            else:
                return False
        elif model._meta.app_label == 'app2':
            return False
        return None

这篇关于使用数据库路由器在Django应用之间共享(mysql)数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆