Django ORM, использующий внешнюю базу данных для неуправляемой модели, говорит, что связь не существует

#python #django #postgresql #orm

#питон #джанго #postgresql #орм

Вопрос:

У меня есть два подключения к базе данных Postgres, и при использовании других вызовов ORM, отличных от стандартных, в представлениях происходит сбой, но не необработанный. Я использую docker, и контейнеры подключены и используют собственную команду runserver от Django. Использование ORM в команде django или оболочке django работает нормально, но не в представлении.

В качестве примечания, обе базы данных на самом деле являются проектами Django, но основной проект считывает некоторые данные непосредственно из базы данных другого проекта, используя собственную неуправляемую модель.

  • Python: 3.9.7
  • Джанго: 3.2.10
  • Postgres: 13.3 (основной проект), 12.2 (побочный проект)
 # settings DATABASES = {  'default': {  'ENGINE': 'django.db.backends.postgresql',  'USER': 'pguser',  'PASSWORD': 'pguser',  'NAME': 'mainproject',  'HOST': 'project-db', # docker container  'PORT': '5432',  },  'external': {  'ENGINE': 'django.db.backends.postgresql',  'USER': 'pguser',  'PASSWORD': 'pguser',  'NAME': 'sideproject',  'HOST': 'side-db', # docker container, attached to same network  'PORT': '5432',  }, }  # My unmanaged model class MyTestModel(models.Model): ​  class Meta:  # table does not exist in 'default', but it does exist in 'external'  db_table = 'my_data_table'   managed = False   # my_data_table is very simple it has id field as integer  # and primary key (works out of the box with django)  # it has normal fields only like IntegerField or CharField  # But even if this model is empty then it returns normally the PK field   # My custom command in Main project # python manage.py mycommand # ... def handle(self, *args, **options):   # This works fine and data from external is populated in MyTestModel  data = MyTestModel.objects.using('external').all()  for x in data:  print(x, vars(x))   # My simple view in Main project  class MyView(TemplateView):   # But using example in views.py, random view class:  def get(self, request, *args, **kwargs):   # with raw works  data = MyTestModel.objects.using('external').raw('select * from my_data_table')  for x in data:  print(x, vars(x))   # This does not work  # throws ProgrammingError: relation "my_data_table" does not exist  data = MyTestModel.objects.using('external').all()  for x in data:  print(x, vars(x))   return super().get(request, *args, **kwargs)   

Так что каким-то образом runserver и представления неправильно генерируют запрос при использовании ORM. Это не может быть ошибкой подключения, потому что при запуске команды или представления с помощью «.raw()» работает.

Теперь самое забавное, что если я изменю «db_table» на что-то общее в обеих базах данных, скажем, «django_content_type» или «фильтр()» и «все()» тоже работают. И да, тогда он действительно возвращает данные из правильной базы данных. Таким образом, если основной проект имеет 50 типов контента, а побочный проект (внешний) имеет 100 типов контента, он фактически возвращает эти 100 типов контента из внешнего.

Я перепробовал все, перестроил докер, создал новые таблицы непосредственно в базе данных, принудительно перезагрузил пользователя postgres и убедился, что все разрешения владельца и все разрешения (в любом случае должны быть в порядке, потому что работает командная сторона). Я даже пытался использовать другую базу данных.

Ответ №1:

Я знаю, что не опубликовал полные настройки и свои локальные настройки, которые могли бы больше помочь в решении этого дела.

Но я заметил, что я установил локально Django Silk, который фиксирует запрос и пытается анализировать запросы к базе данных. Похоже, он, возможно, был загружен слишком рано или ему не нравятся внешние базы данных. Но отключение Django silk из установленных приложений и удаление его промежуточного программного обеспечения устранили проблему.