произвольно типизированные данные в модели Джанго - PullRequest
1 голос
/ 14 апреля 2010

У меня есть модель, скажем, Item. Я хочу хранить в нем произвольное количество атрибутов, таких как title, description, release_date. И я хочу, чтобы они были не просто строками, но имели тип Python, поэтому string, boolean, datetime и т. Д.

Какие у меня есть варианты? Шаблон EAV с отдельной таблицей «имя-значение» не будет работать из-за одного и того же типа БД для всех значений. JSONField, вероятно, может помочь, но он не знает, например, о дате и времени. Кроме того, я смотрел на PickeField, он идеально подходит, но я немного обеспокоен производительностью.

1 Ответ

4 голосов
/ 14 апреля 2010

У вас есть несколько вариантов, и ни один из них не является отличным. Некоторые из них обсуждались до в переполнении стека.

Во-первых, как вы предложили, у вас есть шаблон проектирования значения атрибута сущности.

  • Вы можете добавить проверку типа БД, имея таблицу для VARCHAR, одну для INT и одну для BOOLEAN и т. Д.
  • EAV делает выбор очень болезненным. Вам нужно запросить несколько таблиц, чтобы фактически получить объект, и если вам придется использовать значения из таблицы EAV при поиске, вы столкнетесь с проблемами производительности при увеличении размера.
  • В целом, однако, EAV должен действительно использоваться только для очень разреженных данных, где просто не работает другая опция.
  • Для этого в PyPI есть пакет Django, но я его не использовал.
  • Я видел несколько довольно крупных коммерческих продуктов, которые используют этот подход, когда абсолютно необходима большая гибкость

Немного лучший подход - это иметь таблицу, схема которой изменяется, и таблицу метаданных, которая описывает эту таблицу. Для плотных данных, где большинство элементов имеют большинство атрибутов, это имеет много преимуществ по сравнению с EAV. Этот подход иногда называют динамическими таблицами или динамическими строками.

  • ВСТАВКИ, ОБНОВЛЕНИЯ и УДАЛЕНИЯ намного быстрее, поскольку все в 1-2 таблицах
  • Проверка типов и возможные ограничения могут быть добавлены
  • Однако такой подход оставляет очень сложную базу данных, с которой может быть сложнее работать
  • Я не знаю, как Django использовал бы свою ORM с такой базой данных, поскольку ваши модели менялись бы на лету.
  • Вы изменяете свою базу данных с помощью ALTER TABLE на лету. Вам лучше быть очень осторожным со своими транзакциями

Хороший подход, если вам не нужно выполнять поиск на основе этих динамических атрибутов, - это хранить динамические данные в JSONField или, что еще лучше, в схеме, проверенной XMLField. Однако поиск будет болезненным, если вам придется искать на основе динамического атрибута, который является частью вашего JSON или XML.

Лучший подход зависит от того, насколько разрежены ваши данные и как вы будете искать эти данные. Кроме того, очень хороший вопрос, чтобы спросить, нужна ли вам эта гибкость. Я работал над некоторыми проектами, в которых мы решили, что нам нужен EAV, но с тех пор, как проект вошел в производство, атрибуты редко добавляются и редко удаляются, поэтому мы получили все недостатки и никаких преимуществ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...