Я новичок в SQLAlchemy и реляционных базах данных и пытаюсь создать модель для аннотированной лексики. Я хочу поддержать произвольное количество аннотаций значения ключа для слов, которые могут быть добавлены или удалены во время выполнения. Поскольку в именах клавиш будет много повторений, я не хочу использовать это решение напрямую, хотя код похож.
В моем дизайне есть текстовые объекты и объекты свойств. Слова и свойства хранятся в отдельных таблицах с таблицей property_values, которая связывает их. Вот код:
from sqlalchemy import Column, Integer, String, Table, create_engine
from sqlalchemy import MetaData, ForeignKey
from sqlalchemy.orm import relation, mapper, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
engine = create_engine('sqlite:///test.db', echo=True)
meta = MetaData(bind=engine)
property_values = Table('property_values', meta,
Column('word_id', Integer, ForeignKey('words.id')),
Column('property_id', Integer, ForeignKey('properties.id')),
Column('value', String(20))
)
words = Table('words', meta,
Column('id', Integer, primary_key=True),
Column('name', String(20)),
Column('freq', Integer)
)
properties = Table('properties', meta,
Column('id', Integer, primary_key=True),
Column('name', String(20), nullable=False, unique=True)
)
meta.create_all()
class Word(object):
def __init__(self, name, freq=1):
self.name = name
self.freq = freq
class Property(object):
def __init__(self, name):
self.name = name
mapper(Property, properties)
Теперь я бы хотел сделать следующее:
Session = sessionmaker(bind=engine)
s = Session()
word = Word('foo', 42)
word['bar'] = 'yes' # or word.bar = 'yes' ?
s.add(word)
s.commit()
В идеале это должно добавить 1|foo|42
в таблицу слов, добавить 1|bar
в таблицу свойств и добавить 1|1|yes
в таблицу property_values. Тем не менее, у меня нет правильных сопоставлений и отношений, чтобы это произошло. Читая документацию по http://www.sqlalchemy.org/docs/05/mappers.html#association-pattern, я чувствую, что хочу использовать прокси-сервер ассоциации или что-то в этом роде, но синтаксис для меня неясен. Я экспериментировал с этим:
mapper(Word, words, properties={
'properties': relation(Property, secondary=property_values)
})
но этот маппер заполняет только значения внешнего ключа, и мне нужно заполнить и другое значение. Любая помощь будет принята с благодарностью.