Мой вопрос касается SQLAlchemy, но у меня возникают проблемы с объяснением его словами, поэтому я решил объяснить это простым примером того, чего я пытаюсь достичь:
parent = Table('parent', metadata,
Column('parent_id', Integer, primary_key=True),
Column('name', Unicode),
)
parent_child = Table('parent_child', metadata,
Column('parent_id', Integer, primary_key=True),
Column('child_id', Integer, primary_key=True),
Column('number', Integer),
ForeignKeyConstraint(['parent_id'], ['parent.parent_id']),
ForeignKeyConstraint(['child_id'], ['child.child_id']),
)
child = Table('child', metadata,
Column('child_id', Integer, primary_key=True),
Column('name', Unicode),
)
class Parent(object):
pass
class ParentChild(object):
pass
class Child(object):
pass
>>> p = Parent(name=u'A')
>>> print p.children
{}
>>> p.children[0] = Child(name=u'Child A')
>>> p.children[10] = Child(name=u'Child B')
>>> p.children[10] = Child(name=u'Child C')
Этот код будет создавать 3 строки в таблице parent_child, номер столбца будет 0 для первой строки и 10 для второй и третьей строки.
>>> print p.children
{0: [<Child A>], 10: [<Child B>, <Child C>]}
>>> print p.children[10][0]
<Child B>
(я пропустил весь код сеанса / движка SQLAlchemy в примере, чтобы сделать его максимально чистым)
Я попытался, используя´
collection_class=attribute_mapped_collection('number')
об отношениях между Parent и ParentChild, но это дало мне только одного ребенка на каждое число. Не диктат со списками в нем.
Любая помощь приветствуется!
ОБНОВЛЕНО!
Благодаря Денису Откидачу у меня теперь есть этот код, но он все еще не работает.
def _create_children(number, child):
return ParentChild(parent=None, child=child, number=number)
class Parent(object):
children = association_proxy('_children', 'child', creator=_create_children)
class MyMappedCollection(MappedCollection):
def __init__(self):
keyfunc = lambda attr_name: operator.attrgetter('number')
MappedCollection.__init__(self, keyfunc=keyfunc)
@collection.appender
@collection.internally_instrumented
def set(self, value, _sa_initiator=None):
key = self.keyfunc(value)
try:
self.__getitem__(key).append(value)
except KeyError:
self.__setitem__(key, [value])
mapper(Parent, parent, properties={
'_children': relation(ParentChild, collection_class=MyMappedCollection),
})
Чтобы вставить ребенка, кажется, работает
p.children[100] = Child(...)
Но когда я пытаюсь напечатать детей так:
print p.children
Я получаю эту ошибку:
sqlalchemy.orm.exc.UnmappedInstanceError: Class '__builtin__.list' is not mapped