[英]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.