Django在多个数据库中复制表格

huangapple go评论89阅读模式
英文:

Django duplicate tables with multiple databases

问题

我有多个数据库,一个是sqlite,其他的是postgresql,都在同一个应用程序中使用。当我执行数据库迁移时,所有在models.py中定义的表都会在所有数据库中创建,包括sqlite数据库,或者如果我在allow_migrate函数中添加return False,则什么都不会发生。

如何阻止出现重复的表格?

这是我的代码:

settings.py

  1. DATABASE_ROUTERS = ['routers.router.sqlite_Router','routers.router.postgres_router_1','routers.router.postgres_router_2']
  2. DATABASES = {
  3. 'default': {},
  4. 'auth_db': {
  5. 'ENGINE': 'django.db.backends.sqlite3',
  6. 'NAME': BASE_DIR / 'db.sqlite3',
  7. },
  8. 'postgres_db_1': {
  9. 'ENGINE': 'django.db.backends.postgresql',
  10. 'OPTIONS': {
  11. 'options': '-c search_path=test'
  12. },
  13. 'NAME': 'test1',
  14. 'USER': 'postgres',
  15. 'PORT':'5432',
  16. 'PASSWORD': 'postgres',
  17. 'HOST':'localhost',
  18. },
  19. 'postgres_db_2': {
  20. 'ENGINE': 'django.db.backends.postgresql',
  21. 'OPTIONS': {
  22. 'options': '-c search_path=test'
  23. },
  24. 'NAME': 'test2',
  25. 'USER': 'postgres',
  26. 'PORT':'5432',
  27. 'PASSWORD': 'postgres',
  28. 'HOST':'localhost',
  29. }
  30. }

router.py

  1. class sqlite_Router:
  2. route_app_labels = {'auth', 'contenttypes','admin','sessions'}
  3. database = 'auth_db'
  4. # ...
  5. def allow_migrate(self, db, app_label, model_name=None, **hints):
  6. model = hints.get('model')
  7. if model:
  8. usedb = getattr(model._meta, 'database', None)
  9. if app_label in self.route_app_labels and usedb == self.database:
  10. return db == self.database # True
  11. # else: return False # <= I only get django_migrations, no other tables
  12. return None
  13. class postgres_router_1:
  14. route_app_labels = {'test'}
  15. database = 'postgres_db_1'
  16. # ...
  17. def allow_migrate(self, db, app_label, model_name=None, **hints):
  18. model = hints.get('model')
  19. if model:
  20. usedb = getattr(model._meta, 'database', None)
  21. if app_label in self.route_app_labels and usedb == self.database:
  22. return db == self.database # True
  23. # else: return False # <= I only get django_migrations, no other tables
  24. return None
  25. class postgres_router_2:
  26. route_app_labels = {'test'}
  27. database = 'postgres_db_2'
  28. # ...
  29. def allow_migrate(self, db, app_label, model_name=None, **hints):
  30. model = hints.get('model')
  31. if model:
  32. usedb = getattr(model._meta, 'database', None)
  33. if app_label in this.route_app_labels and usedb == this.database:
  34. return db == this.database # True
  35. # else: return False # <= I only get django_migrations, no other tables
  36. return None

models.py

  1. from django.db import models
  2. models.options.DEFAULT_NAMES = models.options.DEFAULT_NAMES + ('database', )
  3. class postgres_one_test(models.Model):
  4. postgres_test_one = models.CharField(unique=True, max_length=30)
  5. def __str__(self):
  6. return self.postgres_test_one
  7. class Meta:
  8. app_label = 'test'
  9. database = 'postgres_db_1'
  10. class postgres_two_test(models.Model):
  11. postgres_test_two = models.CharField(unique=True, max_length=30)
  12. def __str__(self):
  13. return self.postgres_test_two
  14. class Meta:
  15. app_label = 'test'
  16. database = 'postgres_db_2'
  17. # ...

请注意,Meta类中的database属性指定了每个模型属于哪个数据库。在路由器中,您使用allow_migrate方法来控制哪些应用程序可以迁移到哪个数据库。根据您的配置,每个路由器只应用于特定的应用程序,并将其迁移到相应的数据库。确保您的路由器和模型的配置正确无误,这样您就可以避免重复创建表格。

英文:

I have multiple databases one is sqlite and the others in postgresql using one app, when i migrate bases 'using routers' all the tables in models.py gets created in all the bases including sqlite or nothing if i added return false to the allow_migrate function.

how to stop duplicate tables from happening ??

this is my code 'example'

settings.py

  1. DATABASE_ROUTERS = [&#39;routers.router.sqlite_Router&#39;,&#39;routers.router.postgres_router_1&#39;,&#39;routers.router.postgres_router_2&#39;]
  2. DATABASES = {
  3. &#39;default&#39;: {},
  4. &#39;auth_db&#39;: {
  5. &#39;ENGINE&#39;: &#39;django.db.backends.sqlite3&#39;,
  6. &#39;NAME&#39;: BASE_DIR / &#39;db.sqlite3&#39;,
  7. },
  8. &#39;postgres_db_1&#39;: {
  9. &#39;ENGINE&#39;: &#39;django.db.backends.postgresql&#39;,
  10. &#39;OPTIONS&#39;: {
  11. &#39;options&#39;: &#39;-c search_path=test&#39;
  12. },
  13. &#39;NAME&#39;: &#39;test1&#39;,
  14. &#39;USER&#39;: &#39;postgres&#39;,
  15. &#39;PORT&#39;:&#39;5432&#39;,
  16. &#39;PASSWORD&#39;: &#39;postgres&#39;,
  17. &#39;HOST&#39;:&#39;localhost&#39;,
  18. },
  19. &#39;postgres_db_2&#39;: {
  20. &#39;ENGINE&#39;: &#39;django.db.backends.postgresql&#39;,
  21. &#39;OPTIONS&#39;: {
  22. &#39;options&#39;: &#39;-c search_path=test&#39;
  23. },
  24. &#39;NAME&#39;: &#39;test2&#39;,
  25. &#39;USER&#39;: &#39;postgres&#39;,
  26. &#39;PORT&#39;:&#39;5432&#39;,
  27. &#39;PASSWORD&#39;: &#39;postgres&#39;,
  28. &#39;HOST&#39;:&#39;localhost&#39;,
  29. }
  30. }

router.py

  1. class sqlite_Router:
  2. route_app_labels = {&#39;auth&#39;, &#39;contenttypes&#39;,&#39;admin&#39;,&#39;sessions&#39;}
  3. database = &#39;auth_db&#39;
  4. ....
  5. def allow_migrate(self, db, app_label, model_name=None, **hints):
  6. model = hints.get(&#39;model&#39;)
  7. if model:
  8. usedb = getattr(model._meta, &#39;database&#39;, None)
  9. if app_label in self.route_app_labels and usedb == self.database:
  10. return db == self.database # True
  11. #else: return False # &lt;== i only get django_migrations, no other tables
  12. return None
  13. class postgres_router_1:
  14. route_app_labels = {&#39;test&#39;}
  15. database = &#39;postgres_db_1&#39;
  16. ....
  17. def allow_migrate(self, db, app_label, model_name=None, **hints):
  18. model = hints.get(&#39;model&#39;)
  19. if model:
  20. usedb = getattr(model._meta, &#39;database&#39;, None)
  21. if app_label in self.route_app_labels and usedb == self.database:
  22. return db == self.database # True
  23. #else: return False # &lt;== i only get django_migrations, no other tables
  24. return None
  25. class postgres_router_2:
  26. route_app_labels = {&#39;test&#39;}
  27. database = &#39;postgres_db_2&#39;
  28. ....
  29. def allow_migrate(self, db, app_label, model_name=None, **hints):
  30. model = hints.get(&#39;model&#39;)
  31. if model:
  32. usedb = getattr(model._meta, &#39;database&#39;, None)
  33. if app_label in self.route_app_labels and usedb == self.database:
  34. return db == self.database # True
  35. #else: return False # &lt;== i only get django_migrations, no other tables
  36. return None

models.py

  1. from django.db import models
  2. models.options.DEFAULT_NAMES = models.options.DEFAULT_NAMES + (&#39;database&#39;, )
  3. class postgres_one_test(models.Model):
  4. postgres_test_one = models.CharField(unique=True, max_length=30)
  5. def __str__(self):
  6. return self.postgres_test_one
  7. class Meta:
  8. app_label = &#39;test&#39;
  9. database = &#39;postgres_db_1&#39;
  10. ....
  11. class postgres_two_test(models.Model):
  12. postgres_test_two = models.CharField(unique=True, max_length=30)
  13. def __str__(self):
  14. return self.postgres_test_two
  15. class Meta:
  16. app_label = &#39;test&#39;
  17. database = &#39;postgres_db_2&#39;
  18. ...

答案1

得分: 0

找到了一个解决方案。

更改了django.db.models.options

DEFAULT_NAMES中添加了'database'。

在'class Options'的'init'中添加了'self.database = None'。

并将sqlite_router'django apps->allow_migrate'更改为默认值

  1. if app_label in self.route_app_labels:
  2. return db == self.database
  3. return None

并从allow_migrate中删除'return False'。

还从models中删除了

  1. models.options.DEFAULT_NAMES = models.options.DEFAULT_NAMES + ('database', )

因为它不再需要。其余部分保持不变。

英文:

found A solution.

changed django.db.models.options

added 'database' in the DEFAULT_NAMES

and 'self.database = None' in the 'init' of 'class Options',

and the sqlite_router 'django apps->allow_migrate' to the default

  1. if app_label in self.route_app_labels:
  2. return db == self.database
  3. return None

and removed the 'return False' from the allow_migrate.

also removed

  1. models.options.DEFAULT_NAMES = models.options.DEFAULT_NAMES + (&#39;database&#39;, )

from models as it's not needed.

everything else is the same

huangapple
  • 本文由 发表于 2023年3月4日 08:22:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/75632881.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定