SQLAlchemy:AttributeError:无法在列“_sa_instance_state”的行中找到列

que*_*ing 2 python database sqlite sqlalchemy flask-sqlalchemy

我有一个包含谜题和类别的多对多关系数据库。当我第一次运行它时,一切都运行得非常好。所有表格均已创建并填充内容。但是,当我第二次运行它以进一步填充数据库时,会弹出以下错误。 AttributeError: Could not locate column in row for column '_sa_instance_state'

我已将问题范围缩小到知道当数据库中已找到相同类别时它会崩溃。但不能将其分配给新谜题的类别,因为这就是崩溃发生的地方。

我制作了以下可重现的示例。运行一次就完美了,再次运行就崩溃了。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///example.db'
db = SQLAlchemy(app)

category_identifier = db.Table('category_identifier',
    db.Column('categories_id', db.Integer, db.ForeignKey('categories.id')),
    db.Column('puzzles_id', db.Integer, db.ForeignKey('puzzles.id'))
)

class Puzzle(db.Model):
    __tablename__ = 'puzzles'
    id = db.Column(db.Integer, primary_key=True)
    categories = db.relationship("Category", secondary=category_identifier)


class Category(db.Model):
    __tablename__ = 'categories'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True, nullable=False)


db.create_all()
db.session.commit()

if __name__ == '__main__':

    myList = ['cat1', 'cat2, cat3']
    puzzle = Puzzle()

    for cat in myList:
        category = db.session.query(Category.name).filter_by(name=cat).first()
        
        if not category:
            category = Category(name=cat)

        puzzle.categories.append(category)

    db.session.add(puzzle)
    db.session.commit()
Run Code Online (Sandbox Code Playgroud)

编辑

我发现这两种情况下变量的类型都不同,并且认为这可能是它失败的原因。第一次,变量的类型是<class 'models.Category'>,第二次,当它崩溃时,它是实例的类型<class 'sqlalchemy.engine.row.Row'>

有什么方法可以将变量类型转换为 models.category 类,看看这是否是一个解决方案?

sna*_*erb 6

错误信息

AttributeError:无法在列“_sa_instance_state”的行中找到列

乍一看相当晦涩难懂。这意味着我们正在尝试执行某些特定于模型实例的操作,但执行该操作的对象不是模型实例。

在这种特殊情况下,在执行时

session.add(puzzle)
Run Code Online (Sandbox Code Playgroud)

我们似乎将 aPuzzle及其相关类别添加到会话中,但是结果

db.session.query(Category.name).filter_by(name=cat).first()
Run Code Online (Sandbox Code Playgroud)

将是一行(例如('cat1',),因为我们正在检索一个属性 -Category.name而不是模型实例。

将查询替换为

db.session.query(Category).filter_by(name=cat).first()
Run Code Online (Sandbox Code Playgroud)

将检索模型实例并解决问题。