SQLAlchemy 中的多对一关系

发布于 2024-09-03 22:41:04 字数 1110 浏览 8 评论 0原文

这是一个初级问题。

我有一个 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'

Any想法?

This is a beginner-level question.

I have a catalog of mtypes:

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

and a catalog of Objects, which must have an associated mtype:

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

I am trying to do this in SQLAlchemy by creating the following schemas:

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")}
)

When I try to add a simple element like:

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

I get the error:

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

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

歌枕肩 2024-09-10 22:41:04

您是否尝试过:

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

而不是:

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

另请参阅:https://docs.sqlalchemy。 org/en/13/core/constraints.html

Have you tried:

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

instead of:

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

See also: https://docs.sqlalchemy.org/en/13/core/constraints.html

泪眸﹌ 2024-09-10 22:41:04

我能够运行您上面显示的代码,所以我想当您为了这个问题而简化它时,问题就被消除了。这是正确的吗?

您没有显示回溯,因此只能给出一些一般性提示。

在SQLAlchemy(至少在0.5.8及以上版本)中,只有两个具有“cascade_iterator”属性的对象:sqlalchemy.orm.mapper.Mapper和sqlalchemy.orm.interfaces.MapperProperty。

由于您没有得到 sqlalchemy.orm.exc.UnmappedClassError 异常(所有映射器都在它们应该在的位置),我的疯狂猜测是一些内部 sqlalchemy 代码在应该获取 MapperProperty 实例的地方获取 None 。

在导致异常的 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 的值。很可能由于某种原因它不会是“无”,而罪魁祸首就在那里。

如果 type(invalid_prop) 是 sqlalchemy.orm.properties.RelationshipProperty 那么您在映射器配置中引入了一个错误(对于名为 invalid_prop.key 的关系)。否则在没有更多信息的情况下很难判断。

I was able to run the code you have shown above so I guess the problem was removed when you simplified it for the purpose of this question. Is that correct?

You didn't show a traceback so only some general tips can be given.

In SQLAlchemy (at least in 0.5.8 and above) there are only two objects with "cascade_iterator" attribute: sqlalchemy.orm.mapper.Mapper and sqlalchemy.orm.interfaces.MapperProperty.

Since you didn't get sqlalchemy.orm.exc.UnmappedClassError exception (all mappers are right where they should be) my wild guess is that some internal sqlalchemy code gets None somewhere where it should get a MapperProperty instance instead.

Put something like this just before session.add() call that causes the exception:

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)]

and then use your favourite method (print, python -m, pdb.set_trace(), ...) to check the value of invalid_prop. It's likely that for some reason it won't be None and there lies your culprit.

If type(invalid_prop) is a sqlalchemy.orm.properties.RelationshipProperty then you have introduced a bug in mapper configuration (for relation named invalid_prop.key). Otherwise it's hard to tell without more information.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文