Skip to main content
 首页 » 编程设计

python之使用 Django ORM 加入同一张表

2025年02月15日43mfrbuaa

我目前正在将我们的服务器从 Java 切换到 Python (Django) 并使用 ORM 重新创建我们的 SQL 查询,其中一个被证明是困难的,因为我需要加入同一张表。下面是查询

SELECT  U1.suser, COUNT(U1.id) FROM United U1 INNER JOIN United U2 ON  
U1.sUser = U2.pUser WHERE U2.sUser IN (select sUser from united where pUser = '105660')  
and U1.pUser = '105660' and U1.sUser IN ('580664','1015396') GROUP BY U1.id, U1.suser 

这是我的模型:

class United(models.Model): 
id = models.IntegerField(primary_key=True) 
puser = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, db_column='puser') 
suser = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, db_column='suser', 
                          related_name='secondary_united') 
date = models.DateTimeField(max_length=34, blank=True, null=True, auto_now_add=True) 
 
class Meta: 
    db_table = 'United' 
    unique_together = (('puser', 'suser'),) 

查询是为了找到我(调用用户)和他们所有 friend (ID 列表)之间的相互连接数

查询按照我希望的方式使用直接 SQL(尽管由于这个主键错误,我无法使用 .raw() 方法让它工作)

django.db.models.query_utils.InvalidQuery: Raw query must include the primary key 

但我想找到一种使用 ORM 来完成它的方法。

请您参考如下方法:

我假设您尝试调用查询作为

United.objects.raw(sql) 

正如您提到的那样,这确实会产生错误,因为您的投影 U1.suser, COUNT(U1.id) 没有 id 列。你需要把它改成这样

SELECT U1.id, U1.suser, COUNT(U1.id) FROM United U1 INNER JOIN United U2 ON  
U1.sUser = U2.pUser WHERE U2.sUser IN (select sUser from united where pUser = '105660')  
and U1.pUser = '105660' and U1.sUser IN ('580664','1015396') GROUP BY U1.id, U1.suser 

请注意,它必须是 U1.id 而不是 U2.id 因为您是在 U1.id 上分组的

诚然,使用 ORM 编写此查询有点困难。由于您正在加入 United 本身,而 Django ORM 加入通常仅通过外键或仅通过多对多字段。