SQLAlchemy无法找到类名

Ros*_*oss 27 python sqlalchemy relationships pyramid

简化,我有以下类结构(在单个文件中):

Base = declarative_base()

class Item(Base):
    __tablename__ = 'item'
    id = Column(BigInteger, primary_key=True)
    # ... skip other attrs ...

 class Auction(Base):
     __tablename__ = 'auction'
     id = Column(BigInteger, primary_key=True)
     # ... skipped ...
     item_id = Column('item', BigInteger, ForeignKey('item.id'))

     item = relationship('Item', backref='auctions')
Run Code Online (Sandbox Code Playgroud)

我从这里得到以下错误:

sqlalchemy.exc.InvalidRequestError
InvalidRequestError: When initializing mapper Mapper|Auction|auction, expression
    'Item' failed to locate a name ("name 'Item' is not defined"). If this is a
    class name, consider adding this relationship() to the Auction class after
    both dependent classes have been defined.
Run Code Online (Sandbox Code Playgroud)

我不确定Python如何找不到Item类,因为即使在传递类而不是名称作为字符串时,我也会得到相同的错误.我一直在努力寻找如何与SQLAlchemy建立简单关系的例子,所以如果在这里有一些相当明显的错误我会道歉.

Ros*_*oss 23

这一切都归结为我在Pyramid中设置SQLAlchemy的方式.基本上,您需要按照本节的说明进行操作,并确保使用与declarative_base每个模型的基类相同的实例.

我也没有绑定数据库引擎到我DBSession没有打扰你,直到你尝试访问表元数据,这发生在你使用关系时.


Dee*_*pta 11

跟我一起案例

在单独的文件中定义的两个模型,一个是Parent,另一个是,与外键Child相关。当尝试在芹菜中使用对象时,它给出了Child

sqlalchemy.exc.InvalidRequestError: When initializing mapper Mapper|Child|child, expression 'Parent' failed to locate a name ("name 'Parent' is not defined"). If this is a class name, consider adding this relationship() to the <class 'app.models.child'>
Run Code Online (Sandbox Code Playgroud)

父级.py

from app.models import *


class Parent(Base):
    __tablename__ = 'parent'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    name = Column(String(60), nullable=False, unique=True)
    number = Column(String(45), nullable=False)
Run Code Online (Sandbox Code Playgroud)

孩子.py

from app.models import *


class Child(Base):
    __tablename__ = 'child'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    parent_id = Column(ForeignKey('parent.id'), nullable=False)
    name = Column(String(60), nullable=False)

    parent = relationship('Parent')
Run Code Online (Sandbox Code Playgroud)

解决方案

Parent在开头添加导入语句child.py

child.py(已修改)

from app.models import *
from app.models.parent import Parent  # import Parent in child.py 


class Child(Base):
    __tablename__ = 'child'

    id = Column(BigInteger, primary_key=True, autoincrement=True)
    parent_id = Column(ForeignKey('parent.id'), nullable=False)
    name = Column(String(60), nullable=False)

    parent = relationship('Parent')
Run Code Online (Sandbox Code Playgroud)

为什么这有效

SQLAlchemy 中模型加载的顺序并不固定。
所以,就我而言,Child是在 之前加载的Parent。因此,SQLAlchemy 无法找到什么是Parent. 所以,我们只是在加载Parent之前导入。Child

合十礼


小智 10

如果是子包类,则在子包中添加ItemAuction类到__init__.py

  • 谢谢。现在可以了。但是,您还有其他解决方法来解决这个问题吗?我应该导入 `__init__.py` 文件中的每个模型类吗?我只是想知道是否还有更好的方法。 (4认同)

Chr*_*ert 10

导入所有 SQLAlchemy 模型的 SQLAlchemy 文档部分说明:

但是,由于 SQLAlchemy 的“声明性”配置模式的行为,在成功使用这些模型之前,需要导入所有包含活动 SQLAlchemy 模型的模块。因此,如果您使用具有声明性基础的模型类,您需要找到一种方法来导入所有模型模块,以便能够在您的应用程序中使用它们。

一旦我导入了所有模型(和关系),关于找不到类名的错误就解决了。

  • 注意:我的应用程序不使用 Pyramid,但适用相同的原则。


小智 5

我通过继承“db.Model”而不是“Base”解决了同样的错误......但我正在做烧瓶

例如:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()


class someClass(db.Model):
    someRelation = db.relationship("otherClass")
Run Code Online (Sandbox Code Playgroud)