Django 1.3-dev предоставляет несколько способов запроса базы данных с использованием необработанного SQL. Они покрыты здесь и здесь . Рекомендуемые способы - использовать методы .raw()
или .extra()
. Преимущество состоит в том, что если полученные данные соответствуют Model , вы все равно можете использовать некоторые их функции напрямую.
Страница, которую я пытаюсь отобразить, является несколько сложной, поскольку в ней используется много информации, которая распределена по нескольким таблицам с разными взаимосвязями (one2one, one2many). При текущем подходе сервер должен делать около 4K запросов на страницу. Это очевидно медленно из-за связи базы данных с веб-сервером.
Возможное решение - использовать сырой SQL для извлечения соответствующих данных, но из-за сложности запроса я не смог перевести это на эквивалент в Django.
Запрос:
SELECT clin.iso as iso,
(SELECT COUNT(*)
FROM clin AS a
LEFT JOIN clin AS b
ON a.pat_id = b.pat_id
WHERE a.iso = clin.iso
) AS multiple_iso,
(SELECT COUNT(*)
FROM samptopat
WHERE samptopat.iso_id = clin.iso
) AS multiple_samp,
(SELECT GROUP_CONCAT(value ORDER BY snp_id ASC)
FROM samptopat
RIGHT JOIN samptosnp
USING(samp_id)
WHERE iso_id = clin.iso
GROUP BY samp_id
LIMIT 1 -- Return 1st samp only
) AS snp
FROM clin
WHERE iso IN (...)
или альтернативно WHERE iso = ...
.
Пример вывода выглядит так:
+-------+--------------+---------------+-------------+
| iso | multiple_iso | multiple_samp | snp |
+-------+--------------+---------------+-------------+
| 7 | 19883 | 0 | NULL |
| 8 | 19883 | 0 | NULL |
| 21092 | 1 | 2 | G,T,C,G,T,G |
| 31548 | 1 | 0 | NULL |
+-------+--------------+---------------+-------------+
4 rows in set (0.00 sec)
Документация объясняет, как можно выполнить запрос, используя WHERE col = %s
, но не синтаксис IN
.
Одна часть этого вопроса: Как мне выполнить необработанные SQL-запросы, используя Django и оператор IN
?
Другая часть, учитывая следующие модели:
class Clin(models.Model):
iso = models.IntegerField(primary_key=True)
pat = models.IntegerField(db_column='pat_id')
class Meta:
db_table = u'clin'
class SampToPat(models.Model):
samptopat_id = models.IntegerField(primary_key=True)
samp = models.OneToOneField(Samp, db_column='samp_id')
pat = models.IntegerField(db_column='pat_id')
iso = models.ForeignKey(Clin, db_column='iso_id')
class Meta:
db_table = u'samptopat'
class Samp(models.Model):
samp_id = models.IntegerField(primary_key=True)
samp = models.CharField(max_length=8)
class Meta:
db_table = u'samp'
class SampToSnp(models.Model):
samptosnp_id = models.IntegerField(primary_key=True)
samp = models.ForeignKey(Samp, db_column='samp_id')
snp = models.IntegerField(db_column='snp_id')
value = models.CharField(max_length=2)
class Meta:
db_table = u'samptosnp'
Можно ли переписать приведенный выше запрос в нечто более ориентированное на ORM?