#django #django-tests
#django #django-тесты
Вопрос:
В настоящее время я пишу тесты для нашего приложения django. К сожалению, нам пришлось использовать макет с несколькими базами данных, и мы не можем это изменить. (Распределенные базы данных с несколькими бэкэндами на разных серверах в нескольких центрах обработки данных)
У нас есть две базы данных:
- базы данных по умолчанию с таблицами django по умолчанию
- базы данных приложений с некоторыми моделями
Для этих моделей мы написали разные маршрутизаторы, как описано на сайте django. Теперь проблема, если я запускаю python manage.py test customerreceipts тестовая платформа умирает через несколько секунд со следующей ошибкой:
django.db.utils.ProgrammingError: relation "auth_user" does not exist
Я проверил созданную базу данных, и там не было таблиц. Из-за этого запрос из модели выдает ошибку.
Модель проблемы (в базе данных 2):
class CustomerReceipts(models.Model):
def _choices_user():
users = User.objects.all()
users = users.order_by('id')
return [(e.id, e.username) for e in users]
# General
receipt_name = models.CharField(max_length=20, verbose_name="Receipt name") #: Receipt name
....
# Auditing
owner = models.IntegerField(verbose_name="Owner", choices=[('', '')] _choices_user())
Поскольку настройка нескольких баз данных не поддерживает прямые ссылки, мы используем целочисленное поле для владельца, а бизнес-логика обрабатывает целостность.
Проблема заключается в _choices_user(), который задает запрос для отсутствующей таблицы. Чего я не понимаю, так это почему django не создает таблицу auth_user при первом запуске. Если я удалю приложение с вызывающей моделью, тестовая среда будет работать без каких-либо проблем.
Есть идеи, как это можно исправить?
Спасибо!
Редактировать: я создал одну настройку базы данных и попробовал то же самое. К сожалению, он выдает ту же ошибку! Теперь я в замешательстве. Может ли кто-нибудь проверить это тоже? Создайте модель с помощью метода _choices_user и запустите test.
Комментарии:
1. Добавлен отчет об ошибке в проекте django code.djangoproject.com/ticket/22864#ticket .
Ответ №1:
Вы можете вручную выбрать базу данных. Просто вызовите using() . Метод using() принимает один аргумент: псевдоним базы данных, в которой вы хотите выполнить запрос.
def _choices_user():
users = User.objects.using('default').all()
.....
.....
Комментарии:
1. Звучит многообещающе! Протестирую его, но сначала нужно обновить до django 1.7.
Ответ №2:
Это не совсем идеальный ответ, но единственный способ в настоящее время:
Модель (удаленные варианты):
class CustomerReceipts(models.Model):
# General
receipt_name = models.CharField(max_length=20, verbose_name="Receipt name") #: Receipt name
....
# Auditing
owner = models.IntegerField(verbose_name="Owner")
Администратор:
class CustomerReceiptsAdminForm(forms.ModelForm):
class Meta:
model = CustomerReceipts
users = forms.ChoiceField()
def __init__(self, *args, **kwargs):
super(CustomerReceiptsAdminForm, self).__init__(*args, **kwargs)
owner = self.instance.owner
usersAll = User.objects.all()
usersAll = usersAll.order_by('id')
available_choices = [(e.id, e.username) for e in usersAll]
self.fields['users'].choices = available_choices
self.fields['users'].initial = owner
class CustomerReceipts(admin.ModelAdmin):
fields = ('abc', 'users')
list_display = ('abc', 'get_user')
form = CustomerReceiptsAdminForm
def save_model(self, request, obj, form, change):
obj.owner = form.cleaned_data['users']
obj.save()
def get_user(self, obj):
return User.objects.get(id=obj.owner).username
get_user.short_description = 'User'
Это обработает все отображение в представлении администратора и выберет нужного клиента при редактировании.