Django ORM 和链接 select_related
Django ORM and chained select_related
如何使用 Django ORM 执行此查询?
这是一个多重连接,从 table 链接到 table。
有关 select 相关 (https://docs.djangoproject.com/en/2.2/ref/models/querysets/#select-related) 的 Django 文档给出了一个示例,其中三个 table 通过外键 "chained":Book -> Author -> City .
说
b = Book.objects.select_related('author__hometown').get(id=4)
p = b.author # Doesn't hit the database.
c = p.hometown # Doesn't hit the database.
到 "not hit the database" 必须意味着 select 查询连接三个 table。
因此查询生成的 sql 应该显示(我还没有检查)。
我的模型基于对现有数据库的分析,具有明确定义的外键。
我将在下面摘录模型。
SELECT *
FROM SERVICE
INNER JOIN VISIT ON SERVICE.VisitRecordID = VISIT.VisitRecordID
INNER JOIN CMPATIENT ON VISIT.PatientNo = CM_PATIENT.PATIENT_ID
我可以用
进行的第一个连接
q = Service.objects.select_related('visitrecordid',).all()
这使得 sql 喜欢:
SELECT * FROM [SERVICE] LEFT OUTER JOIN [VISIT] ON ([SERVICE].[VisitRecordID] = [VISIT].[VisitRecordID])
所以我得到的是左外连接,而不是内连接,这是一个问题。
但最重要的是,我不知道为什么 CmPatient 不参与查询。
模型(摘录)
class Service(models.Model):
servrecid = models.AutoField(db_column='ServRecID', primary_key=True) # Field name made lowercase.
visitrecordid = models.ForeignKey('Visit', models.DO_NOTHING, db_column='VisitRecordID', blank=True,
null=True) # Field name made lowercase.
itemno = models.CharField(db_column='ItemNo', max_length=10, blank=True, null=True) # Field name made lowercase.
class Visit(models.Model):
visitrecordid = models.AutoField(db_column='VisitRecordID', primary_key=True) # Field name made lowercase.
patientno = models.ForeignKey(CmPatient, models.DO_NOTHING, db_column='PatientNo', blank=True,
null=True) # Field name made lowercase.
visitdate = models.DateTimeField(db_column='VisitDate', blank=True, null=True) # Field name made lowercase.
servdoctor = models.CharField(db_column='ServDoctor', max_length=6, blank=True,
null=True) # Field name made lowercase.
class CmPatient(models.Model):
patient_id = models.AutoField(db_column='PATIENT_ID', primary_key=True) # Field name made lowercase.
ur_no = models.CharField(db_column='UR_NO', max_length=9, blank=True, null=True) # Field name made lowercase.
external_id = models.CharField(db_column='EXTERNAL_ID', max_length=9, blank=True,
null=True) # Field name made lowercase.
payer = models.ForeignKey('self', models.DO_NOTHING, db_column='PAYER_ID', blank=True,
null=True) # Field name made lowercase.
可以通过__
(两个下划线)遍历关系。所以你想要的是:
Service.objects.select_related('visitrecordid__patientno')
如何使用 Django ORM 执行此查询?
这是一个多重连接,从 table 链接到 table。
有关 select 相关 (https://docs.djangoproject.com/en/2.2/ref/models/querysets/#select-related) 的 Django 文档给出了一个示例,其中三个 table 通过外键 "chained":Book -> Author -> City .
说
b = Book.objects.select_related('author__hometown').get(id=4)
p = b.author # Doesn't hit the database.
c = p.hometown # Doesn't hit the database.
到 "not hit the database" 必须意味着 select 查询连接三个 table。 因此查询生成的 sql 应该显示(我还没有检查)。
我的模型基于对现有数据库的分析,具有明确定义的外键。 我将在下面摘录模型。
SELECT *
FROM SERVICE
INNER JOIN VISIT ON SERVICE.VisitRecordID = VISIT.VisitRecordID
INNER JOIN CMPATIENT ON VISIT.PatientNo = CM_PATIENT.PATIENT_ID
我可以用
进行的第一个连接q = Service.objects.select_related('visitrecordid',).all()
这使得 sql 喜欢:
SELECT * FROM [SERVICE] LEFT OUTER JOIN [VISIT] ON ([SERVICE].[VisitRecordID] = [VISIT].[VisitRecordID])
所以我得到的是左外连接,而不是内连接,这是一个问题。 但最重要的是,我不知道为什么 CmPatient 不参与查询。
模型(摘录)
class Service(models.Model):
servrecid = models.AutoField(db_column='ServRecID', primary_key=True) # Field name made lowercase.
visitrecordid = models.ForeignKey('Visit', models.DO_NOTHING, db_column='VisitRecordID', blank=True,
null=True) # Field name made lowercase.
itemno = models.CharField(db_column='ItemNo', max_length=10, blank=True, null=True) # Field name made lowercase.
class Visit(models.Model):
visitrecordid = models.AutoField(db_column='VisitRecordID', primary_key=True) # Field name made lowercase.
patientno = models.ForeignKey(CmPatient, models.DO_NOTHING, db_column='PatientNo', blank=True,
null=True) # Field name made lowercase.
visitdate = models.DateTimeField(db_column='VisitDate', blank=True, null=True) # Field name made lowercase.
servdoctor = models.CharField(db_column='ServDoctor', max_length=6, blank=True,
null=True) # Field name made lowercase.
class CmPatient(models.Model):
patient_id = models.AutoField(db_column='PATIENT_ID', primary_key=True) # Field name made lowercase.
ur_no = models.CharField(db_column='UR_NO', max_length=9, blank=True, null=True) # Field name made lowercase.
external_id = models.CharField(db_column='EXTERNAL_ID', max_length=9, blank=True,
null=True) # Field name made lowercase.
payer = models.ForeignKey('self', models.DO_NOTHING, db_column='PAYER_ID', blank=True,
null=True) # Field name made lowercase.
可以通过__
(两个下划线)遍历关系。所以你想要的是:
Service.objects.select_related('visitrecordid__patientno')