1

我正在使用多個數據庫(相同postgresql數據庫中的不同模式)在Django 1.9和Python 3.3項目上工作。當我嘗試遷移項目的第一次,我得到這個錯誤使用多個數據庫Django錯誤關係「auth_user」不存在

 
Running migrations: 
    Rendering model states... DONE 
    Applying contenttypes.0001_initial... OK 
    Applying auth.0001_initial... OK 
    Applying MyApp.0001_initial...Traceback (most recent call last): 
    File "/usr/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
psycopg2.ProgrammingError: ERROR: relation "auth_user" does not exist 


The above exception was the direct cause of the following exception: 

Traceback (most recent call last): 
    File "manage.py", line 10, in 
    execute_from_command_line(sys.argv) 
    File "/usr/lib/python3.4/site-packages/django/core/management/__init__.py", line 350, in execute_from_command_line 
    utility.execute() 
    File "/usr/lib/python3.4/site-packages/django/core/management/__init__.py", line 342, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "/usr/lib/python3.4/site-packages/django/core/management/base.py", line 348, in run_from_argv 
    self.execute(*args, **cmd_options) 
    File "/usr/lib/python3.4/site-packages/django/core/management/base.py", line 399, in execute 
    output = self.handle(*args, **options) 
    File "/usr/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 200, in handle 
    executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial) 
    File "/usr/lib/python3.4/site-packages/django/db/migrations/executor.py", line 92, in migrate 
    self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial) 
    File "/usr/lib/python3.4/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards 
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial) 
    File "/usr/lib/python3.4/site-packages/django/db/migrations/executor.py", line 198, in apply_migration 
    state = migration.apply(state, schema_editor) 
    File "/usr/lib/python3.4/site-packages/django/db/backends/base/schema.py", line 90, in __exit__ 
    self.execute(sql) 
    File "/usr/lib/python3.4/site-packages/django/db/backends/base/schema.py", line 110, in execute 
    cursor.execute(sql, params) 
    File "/usr/lib/python3.4/site-packages/django/db/backends/utils.py", line 79, in execute 
    return super(CursorDebugWrapper, self).execute(sql, params) 
    File "/usr/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
    File "/usr/lib/python3.4/site-packages/django/db/utils.py", line 95, in __exit__ 
    six.reraise(dj_exc_type, dj_exc_value, traceback) 
    File "/usr/lib/python3.4/site-packages/django/utils/six.py", line 685, in reraise 
    raise value.with_traceback(tb) 
    File "/usr/lib/python3.4/site-packages/django/db/backends/utils.py", line 64, in execute 
    return self.cursor.execute(sql, params) 
django.db.utils.ProgrammingError: ERROR: relation "auth_user" does not exist 

這個錯誤似乎在其他項目appeard時未遷移的auth_user表。在我的情況下,在遷移需要它的應用程序並不能解決問題之前,開始使用manage.py migrate auth進行遷移。

我懷疑問題來自在Django中使用不同的數據庫。我的auth_user表存儲在默認數據庫中,並且models.py的內容被路由到其他數據庫

遷移過程是否在與我的應用程序數據庫相同的數據庫中查找auth_user表?這是完全不同的東西嗎?

回答

0

對問題的回答

這實際上是一個跨數據庫引用問題。 Django不能創建交叉數據庫外鍵。

Django 1.8 documentation(並沒有在下一版本(當前版本爲1.10)的任何解決方案):

跨數據庫的關係

的Django當前不提供任何支持外鍵或跨多個數據庫的多對多關係。如果您有 使用路由器將模型分區到不同的數據庫,那麼由這些模型定義的任何外鍵和多對多關係在內部都必須爲 。

這是因爲參照完整性。爲了保持兩個對象之間的關係,Django需要知道相關對象的主鍵是有效的。如果主鍵是 存儲在單獨的數據庫上,則無法輕鬆評估主鍵的有效性。

如果你使用的是Postgres,Oracle或MySQL的InnoDB的帶,這是 強制在數據庫完整性級別 - 數據庫級重點 約束防止無法驗證關係的建立。但是,如果您在MyISAM表中使用SQLite或MySQL,則不存在 強制的參照完整性;因此,您可能可以通過 「假」跨數據庫外鍵。然而,這樣的配置是不是 Django在

如何解決辦法,並保持獨立的數據庫

在我的情況下,由於路由器在工作,有一個小黑客以簡化跨數據庫對象的正式支持。

class CrossDBUser(models.Model): 
    user = models.IntegerField() 

    def get_user(self): 
     return User.objects.get(id=self.user) 

    def set_user(self, user): 
     self.user = user.id 

class MyClassWithCrossDB(CrossDBUser): 
    field1 = models.CharField(max_length=200, blank=False) 
    field2 = models.IntegerField(default=0) 

有了這個,我可以使用的方法set_userget_user存儲在我的對象MyClassWithCrossDB用戶的工作。

當然,這並不完美,因爲它不允許像on_delete=models.CASCADE這樣的自動操作,我必須使用方法而不是實例變量。但它是解決方法。