Django теряет коннект с Postgres в момент создания тенанта
Пишу проект на Django с использованием django-tenant.
По логике, при регистрации нового пользователя, должен создаваться новый tenant
,
который должен быть доступен по адресу "project-url.ru/username/..."
Пока для простоты все вешаю на project-url.ru
Вот часть view.py c логикой регистрации:
def create_user_tenant(request):
"""
Создание нового тенанта в момент регистрации нового пользователя
"""
user = UserClass.objects.get(username=request.POST['username'])
schema_name = f'{user.username}_schema'
try:
with transaction.atomic():
tenant = Tenant(schema_name=schema_name, user=user)
tenant.save()
logger.debug(f'Tenant {tenant} created')
domain = Domain(domain=HOST_NAME, tenant=tenant, is_primary=True)
domain.save()
logger.debug(f'Domain {domain} created for tenant {tenant}')
logger.info(f'Tenant for {user.username} was created.')
except IntegrityError as e:
logger.error(f'Error creating tenant or domain for user {user.username}: {e}')
except Exception as e:
logger.error(f'Unexpected error creating tenant or domain for user {user.username}: {e}')
def registration(request):
error_msg = ''
with transaction.atomic():
if request.POST:
logger.debug(f"Registration request")
form = UserRegistrationForm(data=request.POST)
if form.is_valid():
user = form.save()
logger.debug(f"User {user.username} has been registered")
create_user_tenant(request)
return redirect('login')
else:
error_msg = form.error_messages
logger.debug(f"Registration form is invalid. Error {error_msg}")
context = {
'form': UserRegistrationForm(),
'error_msg': error_msg,
}
return render(request, 'users/registration.html', context)
Однако в момент сохранения тенанта tenant.save() получаю ошибку:
The connection 'username_schema' doesn't exist.
При этом, если я делаю тоже самое через ./manage.py shell все работет корректно.
UPD
Через shell срабатывает тоже не сразу, а со второго раза. То есть первый tenant.save() падает в
raise self.exception_class(f"The connection '{alias}' doesn't exist.")
django.utils.connection.ConnectionDoesNotExist: The connection 'username_schema' doesn't exist.
А со второго раза срабатывает штатно. То есть схема в базе создается.
Настройки DB в settings.py:
DATABASES = {
"default": {
'ENGINE': "django_tenants.postgresql_backend",
.....
}
}
DATABASE_ROUTERS = (
'django_tenants.routers.TenantSyncRouter',
)
MIDDLEWARE = [
'django_tenants.middleware.main.TenantMainMiddleware',
...
]
Postgres
запущен в контейнере, запускаю локально на macos 14.5
Прошу помочь разобраться в чем проблема с коннектом к базе.
Так же буду благодарен, если подскажите как организовать доступность тенанта по домену формата "project-url.ru/username/..." (но это второстепенно)e
Ответы (1 шт):
Проблема крылась в том, что у меня был установлен сигнал, который срабатывал до того, как схема создавалась.
Код сигнала:
@receiver(post_save, sender=Tenant)
def create_initial_suppliers(sender, instance, created, **kwargs):
if created: # Проверяем, что тенант был создан
if not SupplierClass.objects.using(instance.schema_name).exists():
*** Тут некоторая логика ***
Однако сигнал мне этот нужен, потому буду разбираться дальше... Но проблему создания схем и тенантов в постгрес я решил.