繁体   English   中英

在 Django 中使用多个数据库

[英]Using Multiple Databases with django

我必须在我的项目中使用多个数据库,但有一个问题。 模型看不到我的数据库。

当我去 localhost:port/admin/app/accounts 它说我没有这样的表:帐户。 模型寻找默认数据库。 不是accounts.db 我该怎么做?

我在互联网上看到的内容中尝试了多种方法,但没有任何反应。

settings.py :
.....
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },

    'accounts': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'accounts.db')
    }
}
.....


models.py:
.....
class Accounts(models.Model):     

    email = models.TextField(blank=True, null=True)                                                                                                                    
    phone = models.TextField(blank=True, null=True)                                                                                                                    
    name = models.TextField(blank=True, null=True)                                                                                                                     
    password = models.TextField(blank=True, null=True)                                                                                                                 
    verify = models.IntegerField(blank=True, null=True)                                                                                                                

    class Meta:                                                                                                                                                        
        managed = False

        db_table = 'accounts'
....


Environment:


Request Method: GET
Request URL: http://localhost:port/admin/hede/accounts/

Django Version: 1.11.23
Python Version: 2.7.15
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'hede']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/usr/local/lib/python2.7/dist-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in wrapper
  552.                 return self.admin_site.admin_view(view)(*args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
  149.                     response = view_func(request, *args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/views/decorators/cache.py" in _wrapped_view_func
  57.         response = view_func(request, *args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/sites.py" in inner
  224.             return view(request, *args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapper
  67.             return bound_func(*args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in _wrapped_view
  149.                     response = view_func(request, *args, **kwargs)

File "/usr/local/lib/python2.7/dist-packages/django/utils/decorators.py" in bound_func
  63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/options.py" in changelist_view
  1564.                 self.list_max_show_all, self.list_editable, self,

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/views/main.py" in __init__
  79.         self.get_results(request)

File "/usr/local/lib/python2.7/dist-packages/django/contrib/admin/views/main.py" in get_results
  177.         result_count = paginator.count

File "/usr/local/lib/python2.7/dist-packages/django/utils/functional.py" in __get__
  35.         res = instance.__dict__[self.name] = self.func(instance)

File "/usr/local/lib/python2.7/dist-packages/django/core/paginator.py" in count
  79.             return self.object_list.count()

File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py" in count
  364.         return self.query.get_count(using=self.db)

File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py" in get_count
  499.         number = obj.get_aggregation(using, ['__count'])['__count']

File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/query.py" in get_aggregation
  480.         result = compiler.execute_sql(SINGLE)

File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py" in execute_sql
  899.             raise original_exception

Exception Type: OperationalError at /admin/hede/accounts/
Exception Value: no such table: accounts

要使用多个数据库,您必须告诉 Django 您将使用的数据库服务器,但将它们添加到 settings.py 中。

多个数据库

    'default': {
        'NAME': 'app_data',
        'ENGINE': 'django.db.backends.postgresql',
        'USER': 'postgres_user',
        'PASSWORD': 's3krit'
    },
    'users': {
        'NAME': 'user_data',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'mysql_user',
        'PASSWORD': 'priv4te'
    }
}

migrate 管理命令一次对一个数据库进行操作。 默认情况下,它在默认数据库上运行,但通过提供 --database 选项,您可以告诉它同步不同的数据库。

$ ./manage.py migrate --database=users
$ ./manage.py migrate --database=customers

您可以在查询查询中手动选择数据库,例如

user = User(....)
user.save(using='users')

Customer.objects.all().using('users')

使用原始游标

with connections['users'].cursor() as cursor:
     cursor.execute("SELECT * FROM users__users")

您也必须将查询路由到数据库(重点是我的):

使用多个数据库的最简单方法是设置数据库路由方案。 默认路由方案确保对象保持“粘性”到其原始数据库(即,从 foo 数据库检索的对象将保存在同一数据库中)。

默认路由方案确保如果未指定数据库,则所有查询都回退到默认数据库

https://docs.djangoproject.com/en/2.1/topics/db/multi-db/#automatic-database-routing

注意:模型 Meta 中的db_table用于数据库的名称,而不是数据库本身的名称!-)

据我所知,您的模型可以看到数据库,但没有使用“帐户”数据库,因为它设置为使用“默认”数据库。 您可以通过创建自定义数据库路由器来更改此设置。

在这里,我假设您的 django 项目目录结构是:

    ./mainapp/
    |--- mainapp/
    |    |--- settings.py
    |    |___ # .....
    |
    |--- app/
    |    |--- apps.py
    |    |--- dbrouters.py # [new file], we will be creating soon.
    |    |--- models.py
    |    |--- views.py
    |    |___ # .....
    |
    |--- manage.py
    |___ # .....

完整示例:

    # app/models.py:
    class Accounts (models.Model):
       # .....
    
    # app/dbrouters.py: # [new file]
    from .models import Accounts
    
    class AccountsDBRouter:
       def db_for_read (self, model, **hints):
          if (model == Accounts):
             # your model name as in settings.py/DATABASES
             return 'accounts'
          return None
       
       def db_for_write (self, model, **hints):
          if (model == Accounts):
             # your model name as in settings.py/DATABASES
             return 'accounts'
          return None
    
    # mainapp/settings.py:
    # .....
    
    INSTALLED_APPS = [
       'app.apps.AppConfig',
       # .....
    ]
    
    # .....
    
    DATABASE_ROUTERS = (
       'app.dbrouters.AccountsDBRouter',
    )
    
    DATABASES = {
       # .....
       'accounts' : {
          # .....
       },
    }
    
    # .....

根据您的要求或规格更改上述代码。

然后,执行以下操作:

$ python3 manage.py makemigrations
$ python3 manage.py migrate --database=accounts
$ python3 manage.py migrate

现在,您应该可以不using('accounts')在代码中使用它,如下所示:

    # app/views.py:
    # .....
    from .models import Accounts
    
    def someview (request):
       accounts = Accounts.objects.all()
       # See, in above line, you're not using:
       # accounts = Accounts.objects.using('accounts').all()
       # as your 'AccountsDBRouter' is already routing read and write
       # db requests to 'accounts' database.
       # Though you can still use "using('accounts')", as it will
       # also provide same results.
    
    def someotherview (request):
       # You can even use the following:
       account = Account(
          email="<email>",
          phone="<phone>",
          # .....
       )
       account.save()
       # Again, this will save directly in 'accounts'.

参考:

希望能回答你。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM