Django:多个数据库,路由器和测试框架

时间:2014-06-18 16:00:39

标签: django django-tests

我正在为我们的django应用程序编写测试。 遗憾的是,我们不得不使用多个数据库布局,无法改变这种情况。 (跨多个数据中心的不同服务器上具有多个后端的分布式数据库)

我们有两个数据库:

  1. 带有django默认表的默认数据库
  2. 包含某些模型的应用程序数据库
  3. 对于这些模型,我们编写了django网站上记录的不同路由器。 现在问题是,如果我运行python manage.py测试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())
    

    由于多个数据库设置不支持直接链接,因此我们为所有者使用IntegerField,业务逻辑处理完整性。

    问题是_choices_user()为缺少的表设置查询。我不明白为什么django在第一次运行时没有创建表auth_user。如果我使用导致模型删除应用程序,则测试框架正常运行。

    任何想法如何解决?

    谢谢!

    编辑: 我创建了一个数据库设置并尝试了同样的事情。可悲的是它抛出同样的错误! 我现在很困惑。有人也可以测试一下吗?使用_choices_user方法创建模型并运行test。

2 个答案:

答案 0 :(得分:1)

您可以手动选择数据库。只需使用()调用即可。方法 using()只接受一个参数:要运行查询的数据库的别名。

def _choices_user():
    users = User.objects.using('default').all()
    .....
    .....

Django 1.7 docs

答案 1 :(得分:0)

这不是一个完美的答案,而是目前唯一的方法:

模型(删除的选项):

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'

这将处理管理视图中的所有显示,并在编辑时选择合适的客户。