簡體   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