交叉表左连接,Django ORM

Posted

技术标签:

【中文标题】交叉表左连接,Django ORM【英文标题】:Cross Table Left Join, Django ORM 【发布时间】:2017-12-07 12:46:08 【问题描述】:

我有以下型号:

class TradeDetails(models.Model):
    created_timestamp = models.DateTimeField(db_column='CREATED_TIMESTAMP', primary_key=True)
    trade_name = models.CharField(db_column='TRADE_NAME', max_length=45)
    trade_image = models.CharField(db_column='TRADE_IMAGE', max_length=500, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'TRADE_DETAILS'


class TradeNotifications(models.Model):
    client_id = models.CharField(db_column='CLIENT_ID', primary_key=True, max_length=15)
    created_timestamp = models.DateTimeField(db_column='CREATED_TIMESTAMP')
    updated_timestamp = models.DateTimeField(db_column='UPDATED_TIMESTAMP', blank=True, null=True)
    platform_notification = models.IntegerField(db_column='PLATFORM_NOTIFICATION', blank=True, null=True)
    sms_notification = models.IntegerField(db_column='SMS_NOTIFICATION', blank=True, null=True)
    email_notification = models.IntegerField(db_column='EMAIL_NOTIFICATION', blank=True, null=True)
    caller_notification = models.IntegerField(db_column='CALLER_NOTIFICATION', blank=True, null=True)
    caller_id = models.IntegerField(db_column='CALLER_ID', blank=True, null=True)
    client_confirmation = models.IntegerField(db_column='CLIENT_CONFIRMATION', blank=True, null=True)
    device_id = models.CharField(db_column='DEVICE_ID', max_length=256, blank=True, null=True)
    platform = models.CharField(db_column='PLATFORM', max_length=15, blank=True, null=True)
    ip_address = models.CharField(db_column='IP_ADDRESS', max_length=50, blank=True, null=True)
    expired = models.IntegerField(db_column='EXPIRED', blank=True, null=True)
    trade_sent = models.IntegerField(db_column='TRADE_SENT', blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'TRADE_NOTIFICATIONS'
        unique_together = (('client_id', 'created_timestamp'),)

我想使用以下 sql 查询对同一数据库上的另一个表执行左连接:

从 TRADE_NOTIFICATIONS LEFT JOIN 中选择 TRADE_DETAILS.TRADE_NAME TRADE_DETAILS ON TRADE_NOTIFICATIONS.CREATED_TIMESTAMP = TRADE_DETAILS.CREATED_TIMESTAMP

是否有更类似于 Django 的方式来执行此操作,或者我应该直接使用 raw sql?

在阅读了一些答案后,我尝试这样做:

TradeNotifications.objects.using('tradenotifications').all().values_list('trade_name', 'trade_details_created_timestamp')

但它引发了一个错误: django.core.exceptions.FieldError: Cannot resolve keyword 'trade_name' into field. Choices are: caller_id, caller_notification,

【问题讨论】:

【参考方案1】:

如果没有模型之间的某些关系(例如外键与 Django ORM),您将无法连接表。模型之间必须存在关系。

这种关系不必在数据库中,如果在模型中定义就足够了,但我认为这对于您的 TradeDetails 和 TradeNotifications 模型是不可能的。您的 client_id 字段可能是可能的;您可以将其从 CharField() 更改为 ForeignKey()。这在您只从数据库中读取数据并对其进行逆向工程并将它们用作非托管模型的情况下尤其有用。

【讨论】:

以上是关于交叉表左连接,Django ORM的主要内容,如果未能解决你的问题,请参考以下文章

SQLServer 多表左连接

MYSQL 表左连接 ON AND 和ON WHERE 的区别

mysql4.0中一表关联多表左连接sql写法:

PostgreSQL同表左外连接多表

oracle 左外连接如果右表中有重复数据如何处理?

cognos如何制作维表左关联事实表的报表