Это вопрос начального уровня.
У меня есть каталог типов:
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 ответа
Попытался ли ты:
Column('mtype_id', ForeignKey('mtypes.mtype_id')),
Вместо того:
Column('mtype_id', None, ForeignKey('mtypes.mtype_id')),
Мне удалось запустить код, который вы показали выше, поэтому я думаю, проблема была устранена, когда вы упростили ее для целей этого вопроса. Это верно?
Вы не показывали трассировку, поэтому можно дать лишь несколько общих советов.
В 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, значит, вы ввели ошибку в конфигурации сопоставителя (для отношения с именем invalid_prop.key). В противном случае без дополнительной информации сложно сказать.
Похожие вопросы
Связанные вопросы
Новые вопросы
python
Python - это многопарадигмальный, динамически типизированный, многоцелевой язык программирования. Он разработан для быстрого изучения, понимания и использования, а также для обеспечения чистого и единообразного синтаксиса. Обратите внимание, что Python 2 официально не поддерживается с 01.01.2020. Тем не менее, для вопросов о Python, связанных с версией, добавьте тег [python-2.7] или [python-3.x]. При использовании варианта Python (например, Jython, PyPy) или библиотеки (например, Pandas и NumPy) включите его в теги.