【问题标题】:How can I do INNER JOIN in Django in legacy database?如何在遗留数据库中的 Django 中进行 INNER JOIN?
【发布时间】:2011-03-03 08:23:41
【问题描述】:

抱歉,这个问题可能很简单,但我是 Django 的新手,真的很困惑。

我有一个丑陋的旧表,我无法更改。
它有 2 个表:

class Salespersons(models.Model):
    id = models.IntegerField(unique=True, primary_key=True)
    xsin = models.IntegerField()
    name = models.CharField(max_length=200)
    surname = models.CharField(max_length=200)

class Store(models.Model):
    id = models.IntegerField(unique=True, primary_key=True)
    xsin = models.IntegerField()
    brand = models.CharField(max_length=200)

所以我想我不能在类定义中添加外键,因为它们会更改表。

我需要执行这样的sql请求:

SELECT * FROM Salespersons, Store INNER JOIN Store ON (Salespersons.xsin = Store.xsin);

如何使用 Django ORM 实现它?
或者我可以分别获得 Salespersons 和 Store,即

stores = Store.objects.filter(xsin = 1000)
salespersons = Salespersons.objects.filter(xsin = 1000)

【问题讨论】:

  • 这取决于您到底要检索什么。 xsin 是什么意思?它是否“指向”第三张桌子?
  • xsin 是用于连接某些表的字段。是的,可以用来加入第三张表。

标签: python django django-models


【解决方案1】:

根据您的示例查询,您的 tables 实际上是否命名为 Salespersons/Store? 无论如何,这样的事情应该可以工作:

results = Salespersons.objects.extra(tables=["Store"],
                          where=["""Salespersons.xsin = Store.xsin"""])

但是,考虑到表/模型的名称,在我看来,内部连接在逻辑上并不正确。除非您总是每家商店只有 1 名销售人员使用相同的 xsin

【讨论】:

    【解决方案2】:

    如果您可以使xsin 字段之一唯一,您可以使用带有to_field 的ForeignKey 来生成内部连接,如下所示:

    class Salespersons(models.Model):
        xsin = models.IntegerField(unique=True)
    
    class Store(models.Model):
        xsin = models.ForeignKey(Salespersons, db_column='xsin', to_field='xsin')
    
    >>> Store.objects.selected_related('xsin')
    

    【讨论】:

    • 谢谢你,真的很有价值。但是,如果我想在 Store 类中创建另一个外键怎么办。此外键将指向另一个表,例如 class StoreCredentials(models.Model): xsin = models.IntegerField(unique=True)。有没有可能实现?
    【解决方案3】:

    我不明白为什么即使数据库缺少约束也不能使用models.ForeignKey 字段——如果您不显式执行 SQL 来更改数据库,那么表将不会更改。如果您使用ForeignKey,那么您可以使用Salespersons.objects.select_related('xsin') 请求同时获取相关对象。

    【讨论】:

    • 你能提供一个外键的例子吗?
    • class Salespersons(models.Model): id = models.IntegerField(unique=True, primary_key=True) xsin = models.IntegerField() name = models.CharField(max_length=200) surname = models .CharField(max_length=200) store = models.ForeignKey(Customer) 如果我这样做,如果我理解正确,Django 将创建 store_id 字段
    • 对不起。我的意思是:store = models.ForeignKey(Customer)
    • @gennad:是的,它将创建带有 FK 约束的 store_id。但是,您为什么要将 store 命名为面向客户的 FK 字段?
    • 嗯...抱歉,没听懂。我怎样才能实现使用外键?有没有更好的办法?
    猜你喜欢
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 2011-01-17
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-07
    相关资源
    最近更新 更多