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

1

Недавно я работал с 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'.

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

Теги:
sqlalchemy
entity-attribute-value
pylons

1 ответ

4

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

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

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

Я полагаю, что я бы пошел либо с чем-то, основанным на примере вертикального сопоставления атрибутов, либо с помощью ассоциациипрокси/

Ещё вопросы

Сообщество Overcoder
Наверх
Меню