Django - Устаревшие таблицы базы данных - Запрос 2 к нескольким таблицам - PullRequest
2 голосов
/ 19 января 2020

Я новичок в Django и хотел бы получить совет о том, как сделать запрос из 3 таблиц.

У меня есть 3 таблицы из устаревшей базы данных, сопоставленные с моделями (Patient, PrescribedMeds, PrescribedMedsSchedule). Мы не можем изменить эту структуру, так как она должна оставаться активной, пока мы создаем приложение Django.

1 пациент может иметь много прописанных лекарств. 1 прописанное лекарство может иметь несколько раз в расписании

Ниже приведена модель в django.

models.py

class Patient(models.Model):
    patient_name = models.CharField(db_column='patient_name', max_length=50)  
    dob = models.DateTimeField(db_column='DOB', blank=True, null=True)  # Field name made lowercase.
    gender = models.CharField(db_column='Gender', max_length=7)  # Field name made lowercase.
    dateofentry = models.DateTimeField(db_column='DateOfEntry', blank=True, null=True)  # Field name made lowercase.
    ....
    ....

    class Meta:
        managed = False
        db_table = 'patient'

    def __str__(self):
            return self.patient_name

class PrescribedMeds(models.Model):
    #id = models.AutoField(db_column='ID', primary_key=True)  # Field name made lowercase.
    patient_id= models.ForeignKey(Patient, models.DO_NOTHING, db_column='patient_id')
    med_type = models.SmallIntegerField(db_column='Type')  # Field name made lowercase.
    name_of_medication = models.CharField(db_column='Name_Of_Medication', max_length=50, blank=True, null=True)  # Field name made lowercase.
    rxno = models.CharField(db_column='RxNo', max_length=50, blank=True, null=True)  # Field name made lowercase.
    date_filled = models.DateTimeField(db_column='DateFilled', blank=True, null=True)  # Field name made lowercase.
    ....
    ....

    class Meta:
        managed = False
        db_table = 'prescribed_meds'

    def __str__(self):
            return str(self.id) + ", " + self.name_of_medication + ", " + str(self.childno)

class PrescribedMedsSchedule(models.Model):
    #id = models.AutoField(db_column='ID', primary_key=True)  # Field name made lowercase.
    prescribed_meds_id = models.ForeignKey(PrescribedMeds, models.DO_NOTHING, db_column='prescribed_meds_ID')  # Field name made lowercase.
    medication_date = models.DateField()
    medication_time = models.DateTimeField()
    quantity = models.DecimalField(max_digits=6, decimal_places=2, blank=True, null=True)
    form = models.CharField(max_length=1, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'prescribed_meds_schedule'

Я пытаюсь получить право синтаксис в Django для отображения данных из 3 столбцов (Prescribed_Meds.ID, PrescribedMeds.name_of_medication, Patient.patient_name, PrescribedMedsSchedule.medication_date, PrescribedMedsSchedule.medication_time).

В SQL запрос будет

SELECT prescribed_meds.ID, prescribed_meds.Name_Of_Medication, patient.patient_name, prescribed_meds_schedule.medication_date, prescribed_meds_schedule.medication_time
FROM prescribed_meds_schedule 
INNER JOIN (prescribed_meds INNER JOIN patient ON prescribed_meds.patient_id = patient.id) ON prescribed_meds_schedule.prescribed_meds_ID = prescribed_meds.ID;

Какой будет правильный запрос в Django? У меня возникла проблема, так как нет связи от PrescribedMedsSchedule до Patient таблицы.

Я пробовал следующее:

my_obj = PrescribedMedsSchedule.objects.all().selected_related(
    'prescribed_meds_id'
).prefetch_related('PrescribedMeds__patient_id')

Однако этот запрос не вызывает Patient таблицу / модель.

Любой совет будет оценен.

1 Ответ

1 голос
/ 20 января 2020

Стоит начать с примечания о том, что django делает внутри с ФК. У вас есть суффикс в ваших моделях _id, но django сделает это автоматически для столбца базы данных. Таким образом, в вашей модели у вас может быть более легкое для чтения поле, patient = models.ForeignKey(Patient), и оно будет patient_id в базе данных.

select_related следует отношениям с внешним ключом, так что вы Правильно сделать это. Если вы хотите INNER присоединиться , вы должны следовать внешним ключам. В вашем случае используйте двойное подчеркивание для просмотра моделей:

PrescribedMedsSchedule.objects.all().select_related(
    'prescribed_meds_id'
).select_related('prescribed_meds_id__patient_id')

Или вы можете использовать 2 запроса и использовать значения id из PrescribedMeds, чтобы затем запросить PrescribedMedsSchedule. Это было бы что-то вроде:

meds = PrescribedMeds.objects.all().select_related('patient_id')

med_ids = meds.values_list('id', flat=True)

schedules = PrescribedMedsSchedule.objects.filter(prescribed_meds_id__in=med_ids)
...