Для прямого ответа перейдите к пункту 6)
Давайте поговорим шаг за шагом.
1) N: M выберите .Вы говорите, что хотите запрос, подобный следующему:
SELECT *
FROM a JOIN ab_relation ON ab_relation.a_id = a.id
JOIN b ON ab_relation.b_id = b.id;
Но это не настоящий запрос N: M, поскольку вы получаете только объекты, связанные с AB. В запросе следует использовать outer joins
.По крайней мере, как:
SELECT *
FROM a left outer JOIN
ab_relation ON ab_relation.a_id = a.id left outer JOIN
b ON ab_relation.b_id = b.id;
В других случаях вы получаете только A
модели с соответствующими B
.
2) Чтение больших таблиц Вы говорите "умеренно большие столы" .Тогда вы уверены, что хотите прочитать всю таблицу из базы данных?В веб-среде это не принято для чтения большого количества данных, и в этом случае вы можете разбивать данные на страницы.Может быть, это не веб-приложение?Зачем вам нужно читать эти большие таблицы?Нам нужен контекст, чтобы ответить на ваш вопрос.Вы уверены, что вам нужны все поля из обеих таблиц?
3) Выберите * из Вы уверены, что вам нужны все поля из обеих таблиц?Может быть, если вы прочитаете только некоторые значения, этот запрос будет выполняться быстрее.
A.objects.values( "some_a_field", "anoter_a_field", "Bs__some_b_field" )
4) Как сводка .ORM - мощный инструмент, две отдельные операции чтения являются «быстрыми».Я пишу некоторые идеи, но, возможно, нам нужно больше контекста, чтобы ответить на ваш вопрос.Что означает умеренные большие таблицы, пшеница означает медленный, что вы делаете с этими данными, сколько полей или байтов имеет каждая строка из каждой таблицы, ....
Editedd Поскольку OP имеетотредактировал вопрос.
5) Используйте правильные элементы управления пользовательского интерфейса .Вы говорите:
Набор запросов будет использоваться в качестве параметров для поля выбора с несколькими вариантами выбора, где нам нужно будет представить объекты A, имеющие отношение с B, с дополнительной строкой из B.field.
Выглядит как анти-шаблон для отправки клиенту 4k строк для формы.Я предлагаю вам перейти на живой контроль, который загружает только необходимые данные.Например, фильтрация по некоторому тексту.Взгляните на django-select2 потрясающий проект.
6) Вы говорите
Вопрос: возможно ли получить запрос на левое соединение, написанный вручнуючерез ORM?
Ответ: Да , вы можете сделать это, используя values
, как я сказал в пункте 3. Пример: Material
и ResultatAprenentatge
является отношением N: M:
>>> print( Material
.objects
.values( "titol", "resultats_aprenentatge__codi" )
.query )
Запрос:
SELECT "material_material"."titol",
"ufs_resultataprenentatge"."codi"
FROM "material_material"
LEFT OUTER JOIN "material_material_resultats_aprenentatge"
ON ( "material_material"."id" =
"material_material_resultats_aprenentatge"."material_id" )
LEFT OUTER JOIN "ufs_resultataprenentatge"
ON (
"material_material_resultats_aprenentatge"."resultataprenentatge_id" =
"ufs_resultataprenentatge"."id" )
ORDER BY "material_material"."data_edicio" DESC