【问题标题】:SQL Alchemy AttributeError: 'str' object has no attribute '_sa_instance_state'SQLAlchemy AttributeError:“str”对象没有属性“_sa_instance_state”
【发布时间】:2021-12-27 21:07:50
【问题描述】:

我正在尝试向数据库表中添加一个新元素,但我不断收到此错误。 我的数据库是这样的:

class User(UserMixin, db.Model):
    __tablename__ = "users"
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(100), unique=True)
    password = db.Column(db.String(100))
    name = db.Column(db.String(100))
    posts = relationship("BlogPost", back_populates="author")


class BlogPost(db.Model):
    __tablename__ = "blog_posts"
    id = db.Column(db.Integer, primary_key=True)

    # Create Foreign Key, "users.id" the users refers to the tablename of User.
    author_id = db.Column(db.Integer, db.ForeignKey("users.id"))
    # Create reference to the User object, the "posts" refers to the posts property in the User class.
    author = relationship("User", back_populates="posts")

    title = db.Column(db.String(250), unique=True, nullable=False)
    subtitle = db.Column(db.String(250), nullable=False)
    date = db.Column(db.String(250), nullable=False)
    body = db.Column(db.Text, nullable=False)
    img_url = db.Column(db.String(250), nullable=False)

我用来创建新博文的功能是这样的:

    form = CreatePostForm()
    if form.validate_on_submit():
        new_post = BlogPost(
            title=form.title.data,
            subtitle=form.subtitle.data,
            body=form.body.data,
            img_url=form.img_url.data,
            author=current_user.name,
            author_id=current_user.id,
            date=date.today().strftime("%B %d, %Y")
        )
        db.session.add(new_post)
        db.session.commit()
        return redirect(url_for("get_all_posts"))
    return render_template("make-post.html", form=form)

我指定在链接这两个表之前,代码运行良好。当我在两个表之间创建关系时出现问题。

提前感谢您的帮助!

【问题讨论】:

  • 您已经定义了一个关系来引用用户(作者)。但是,在您的路线中,您传递用户的名称和用户的 ID。只需将 current_user 作为作者或仅将 current_user.id 作为 author_id 传递,那么它应该可以工作。
  • 成功了!!非常感谢,但您能向我解释一下为什么会出现这个错误吗?我是关系数据库主题的新手,我不确定我是否理解其中的逻辑。
  • 关系是到另一个模型的虚拟映射。您传递了一个字符串,而不是一个对象的实例。无法使用此信息进行映射。关系基于存储在表列中的 ForeignKey。从现在开始,可以从另一个表中读取引用对象的列。所以你只需要设置代表 ForeignKey 的属性,或者期望关系的对象。如果设置对象,会自动设置 ForeignKey,反之亦然。
  • 好的,所以如果我对关系数据库的理解正确,您可以放置​​外键或链接与父表关系的“变量”。对吗?

标签: flask sqlalchemy flask-sqlalchemy


【解决方案1】:

关系数据库使用外键来引用相关记录。这总是指另一个表的唯一主键。因此,您定义了一个链接,在该链接中定义了一个列外键,它指向另一个表的主键。这意味着可以使用 SQL JOIN 语句来查询引用的数据记录。

您还可以在 SQLAlchemy 中定义关系。这会自动加载引用数据集的列并创建相应模型类的对象的实例。您可以直接从模型请求一个或多个对象,具体取决于关系(ONE ONE、ONE MANY、MANY ONE、MANY MANY)。这是虚拟关系。它只是用来做类映射,是可选的,不是数据库的属性。

使用 SQLAlchemy 创建对象时,就像在路由中所做的那样,您可以设置引用 ID(外键;作者 ID),或者传递整个引用对象(作者/当前用户)。如果使用第一个变体,则直接设置外键。如果选择第二种方案,主键(id)列会自动分配给后台定义为外键(author_id)的列。

实际的关系是由外键和主键之间的链接来定义的。这是数据库的属性。对象的查找由 SQLAlchemy 关系定义,并反映了 ORM(对象关系映射)的一部分。它是 SQLAlchemy 的一个属性。

您的错误是您将字符串而不是模型类中的对象传递给构造函数。所以映射无法工作。

【讨论】:

  • 哦……好吧……我现在明白了。非常感谢!
猜你喜欢
  • 2016-01-10
  • 2020-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-23
  • 1970-01-01
  • 2019-04-27
  • 2013-04-15
相关资源
最近更新 更多