【问题标题】:Django: Multiple Databases, Routers and Test FrameworkDjango:多个数据库、路由器和测试框架
【发布时间】:2014-08-09 00:32:01
【问题描述】:

我目前正在为我们的 django 应用程序编写测试。 可悲的是,我们不得不使用多数据库布局并且无法更改这一点。 (跨多个数据中心的不同服务器上具有多个后端的分布式数据库)

我们有两个数据库:

  1. 带有 django 默认表的默认数据库
  2. 具有某些模型的应用程序数据库

对于这些模型,我们编写了不同的路由器,如 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())

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

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

有什么办法可以解决这个问题吗?

谢谢!

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

【问题讨论】:

标签: django django-tests


【解决方案1】:

您可以手动选择数据库。只需调用 using()。方法 using() 采用单个参数:您要在其上运行查询的数据库的别名。

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

Django 1.7 docs

【讨论】:

  • 这听起来很有希望!将对其进行测试,但需要先更新到 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'

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 2018-07-03
    • 1970-01-01
    • 2012-03-28
    • 2017-02-13
    • 2019-09-26
    相关资源
    最近更新 更多