Многозначные отношения в SQLAlchemy - PullRequest
1 голос
/ 01 июня 2010

Это вопрос начального уровня.

У меня есть каталог mtypes:

mtype_id name
       1 'mtype1'
       2 'mtype2'
[etc]

и каталог объектов, который должен иметь связанный mtype:

obj_id mtype_id name
     1        1 'obj1'
     2        1 'obj2'
     3        2 'obj3'
[etc]

Я пытаюсь сделать это в SQLAlchemy, создав следующие схемы:

mtypes_table = Table('mtypes', metadata,
 Column('mtype_id', Integer, primary_key=True),
 Column('name', String(50), nullable=False, unique=True),
)

objs_table = Table('objects', metadata,
 Column('obj_id', Integer, primary_key=True),
 Column('mtype_id', None, ForeignKey('mtypes.mtype_id')),
 Column('name', String(50), nullable=False, unique=True),
)

mapper(MType, mtypes_table)
mapper(MyObject, objs_table, 
 properties={'mtype':Relationship(MType, backref='objs', cascade="all, delete-orphan")}
)

Когда я пытаюсь добавить простой элемент, такой как:

mtype1 = MType('mtype1')
obj1 = MyObject('obj1')
obj1.mtype=mtype1
session.add(obj1)

Я получаю ошибку:

AttributeError: 'NoneType' object has no attribute 'cascade_iterator'

Есть идеи?

Ответы [ 2 ]

2 голосов
/ 02 июня 2010

Вы пробовали:

Column('mtype_id', ForeignKey('mtypes.mtype_id')),

вместо:

Column('mtype_id', None, ForeignKey('mtypes.mtype_id')),

Смотри также: http://www.sqlalchemy.org/docs/05/reference/sqlalchemy/schema.html#sqlalchemy.schema.ForeignKey

0 голосов
/ 07 июня 2010

Мне удалось запустить код, который вы показали выше, поэтому я думаю, что проблема была устранена, когда вы упростили ее для целей этого вопроса.Это правильно?

Вы не показали трассировку, поэтому можно дать только некоторые общие советы.

В SQLAlchemy (по крайней мере, в 0.5.8 и выше) есть только два объекта сАтрибут "cascade_iterator": sqlalchemy.orm.mapper.Mapper и sqlalchemy.orm.interfaces.MapperProperty.

Поскольку вы не получили исключение sqlalchemy.orm.exc.UnmappedClassError (все сопоставители находятся там, где они должны быть)) мое дикое предположение состоит в том, что некоторый внутренний код sqlalchemy получает значение None где-то, где вместо него должен быть получен экземпляр MapperProperty.

Поместите что-то подобное непосредственно перед вызовом session.add (), который вызывает исключение:

from sqlalchemy.orm import class_mapper
from sqlalchemy.orm.interfaces import MapperProperty

props = [p for p in class_mapper(MyObject).iterate_properties]
test = [isinstance(p, MapperProperty) for p in props]
invalid_prop = None
if False in test:
    invalid_prop = props[test.index(False)]

и затем используйте ваш любимый метод (print, python -m, pdb.set_trace (), ...), чтобы проверить значение invalid_prop.Вероятно, по какой-то причине это не будет None, и в этом ваш виновник.

Если тип (invalid_prop) является sqlalchemy.orm.properties.RelationshipProperty, то вы ввели ошибку в конфигурацию mapper (для отношенияпо имени invalid_prop.key).В противном случае трудно сказать без дополнительной информации.

...