简化后,我有以下类结构(在单个文件中):
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')
我从中得到以下错误:
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.
我不确定Python如何找不到Item类,因为即使传递类而不是字符串形式的名称,我也会得到相同的错误。我一直在努力寻找如何与 SQLAlchemy 建立简单关系的示例,因此如果这里有一些相当明显的错误,我深表歉意。
这一切都是因为我在 Pyramid 中设置 SQLAlchemy 的方式所致。本质上,您需要严格遵循本节,并确保使用相同的
declarative_base
实例作为每个模型的基类。
我也没有将数据库引擎绑定到我的
DBSession
,这不会打扰您,直到您尝试访问表元数据(这在您使用关系时会发生)。
如果是子包类,则将
Item
和 Auction
类添加到子包中的 __init__.py
SQLAlchemy 文档中关于 导入所有 SQLAlchemy 模型的部分内容:
但是,由于 SQLAlchemy 的“声明式”配置模式的行为,需要先导入所有包含活动 SQLAlchemy 模型的模块,然后才能成功使用这些模型。因此,如果您使用具有声明性基础的模型类,您需要找到一种方法来导入所有模型模块,以便能够在您的应用程序中使用它们。
导入所有模型(和关系)后,有关找不到类名的错误就解决了。
在单独的文件中定义两个模型,一个是
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'>
parent.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)
child.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')
在
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')
SQLAlchemy 中模型加载的顺序不固定。
因此,就我而言,
Child
在 Parent
之前加载。因此,SQLAlchemy 无法找到 Parent
是什么。因此,我们只是在加载 Parent
之前导入了 Child
。
我通过继承“db.Model”而不是“Base”解决了同样的错误......但我正在做烧瓶
例如:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class someClass(db.Model):
someRelation = db.relationship("otherClass")
此外,即使这不适用于OP,对于任何登陆此处并遇到相同错误的人,请检查以确保您的表名中没有破折号。
例如,名为“movie-genres”的表在 SQLAlchemy 关系中用作辅助表将生成相同的错误
"name 'movie' is not defined"
,因为它只会读取破折号。切换到下划线(而不是破折号)可以解决问题。
一个模型文件,如果需要,甚至更多。
模型.py
from sqlalchemy import Boolean, BigInteger, Column, DateTime, Float, ForeignKey, BigInteger, Integer, String
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from .parent import Parent
from .child import Child
parent.py
from sqlalchemy import Boolean, BigInteger, Column, DateTime, Float, ForeignKey, BigInteger, Integer, String
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
#Base = declarative_base()
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)
child.py
from sqlalchemy import Boolean, BigInteger, Column, DateTime, Float, ForeignKey, BigInteger, Integer, String
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
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')
相同的 Deepam 答案,但只需一个 models.py 文件即可导入另一个模型
我有一个不同的错误,但这里的答案帮助我解决了它。
我收到的错误:
sqlalchemy.exc.InvalidRequestError: When initializing mapper mapped class Parent->parents, expression 'Child' failed to locate a name ('Child'). If this is a class name, consider adding this relationship() to the <class 'parent.Parent'> class after both dependent classes have been defined.
我的设置与Deepam的答案类似。
简单介绍一下我所做的不同之处:
导致错误的原因:
修复了什么:
我还有另一个解决方案,但这帮助我找到了线索。我试图使用“https://docs.sqlalchemy.org/en/14/orm/examples.html#versioning-objects”来实现版本控制History_mapper”类。
我也遇到了同样的错误。要解决这个问题,我所要做的就是更改模型导入的顺序。
models/__init__.py
Base = declarative_base()
class Item(Base):
__tablename__ = 'item'
id = Column(BigInteger, primary_key=True)
# ... skip other attrs ...
auctions = relationship('Auction', back_populates='item')
class Auction(Base):
__tablename__ = 'auction'
id = Column(BigInteger, primary_key=True)
# ... skipped ...
item_id = Column('item', BigInteger, ForeignKey('item.id'))
item = relationship('Item', back_populates='auctions')