Как я могу объединить удивительность схем SQLAlchemy и EAV DB? - PullRequest
1 голос
/ 03 августа 2010

Недавно я работал с Pylons и очень похож на модель SQLAlchemy для взаимодействия с базой данных.Хотя есть один раздел моего веб-сайта, который, я думаю, мог бы выиграть от схемы EAV.

Используя это в качестве примера моей таблицы:

id | userid | type   | value
---+--------+--------|------------
1  |  1     |  phone | 111 111 111
---+--------+--------|------------
2  |  1     |  age   | 40

Я могу вручную выполнить запросы, подобные приведенным ниже, для извлечения иобновить данные:

SELECT value FROM table WHERE userid=1 AND type='phone'
UPDATE table SET value=41 WHERE userid=1 AND type='age'

Это просто и работает ... Но создание запросов вручную не является моим предпочтительным подходом.Я хочу использовать SQLAlchemy для создания моей табличной модели и позволить ей выполнять всю работу по ногам.

Если бы я использовал стандартную схему, где у каждого type был свой собственный столбец, я мог бы сделать следующее:

class People(Base):

   __tablename__ = 'people'

   id      = Column(Integer, primary_key=True)
   userid  = Column(Integer, ForeignKey('users.id'))
   phone   = Column(Unicode(40))
   age     = Column(Integer)

Затем я мог бы извлечь данные, используя:

data = Session.query(People).filter_by(id=1).first()
print data.age

Я хочу сделать то же самое для моей схемы EAV.В общем, мне нужен способ расширить SQLAlchemy и сказать ему, что когда я вызываю data.age, это фактически означает, что я хочу SELECT value FROM table WHERE id=1 AND type='age'.

Это выполнимо?Или я буду вынужден загромождать свой код запросами, выданными вручную?

1 Ответ

5 голосов
/ 03 августа 2010

Посмотрите примеры вертикального отображения атрибутов .Я думаю, что это более или менее то, что вы после.В примерах представлен диктовочный интерфейс, а не атрибуты, как в вашем примере (вероятно, лучше для произвольных ключей метаданных, а не для нескольких конкретных атрибутов).

Если вы предпочитаете отображать каждый атрибут отдельно: вещи вдокументы, которые могут представлять интерес:

  • выражения sql как сопоставленные атрибуты : как вы действительно можете сопоставить атрибут с произвольным выражением sql (только для чтения)
  • изменение поведения атрибута , особенноиспользование дескрипторов и пользовательских компараторов: все сводится к тому, чтобы просто использовать обычные свойства python для ваших атрибутов и делать все, что вам нужно, с помощью get / set +, при необходимости предписывая, как должно работать сравнение с другими значениями (для запросов). associationproxy : в основном обеспечивает более простое представление об отношении.Например, в вашем случае вы могли бы сделать _age отношением к вашему KeyValue (или как вы хотите его называть), используя пользовательское условие соединения (не только идентификатор пользователя, но также указав тип "age") и используя uselist=False (поскольку для каждого пользователя существует только один возраст, требуется одно значение, а не список).Затем вы могли бы использовать age = association_proxy('_age', 'value'), чтобы он «показывал» только значение, а не весь объект KeyValue.

Полагаю, я бы выбрал что-то на основе примера сопоставления вертикальных атрибутов,или с ассоциацией proxy /

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