在此代码中 last_seen 每当用户使用该站点时,字段都会刷新为当前时间。然而,在对数据库的调用中,他(Minuel Grindberg“Flask Web Development”)补充道 self 代替 self.last_seen, ,这让我很困惑。我了解 OOP 的基本原理,并且我(认为)了解什么 self 是(引用正在创建的对象),但我不明白为什么我们不添加 self.last_seen 在最后一行 db.session.add(self)?完整代码如下。。。

class User(UserMixin, db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)
    username = db.Column(db.String(64), unique=True, index=True)
    role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
    password_hash = db.Column(db.String(128))
    confirmed = db.Column(db.Boolean, default=False)
    name = db.Column(db.String(64))
    location = db.Column(db.String(64))
    about_me = db.Column(db.Text())
    member_since = db.Column(db.DateTime(), default=datetime.utcnow)
    last_seen = db.Column(db.DateTime(), default=datetime.utcnow)

def ping(self):
    self.last_seen = datetime.utcnow()
    db.session.add(self)

看起来很简单,我确信确实如此,但显然我错过了一些东西,或者没有学到我应该学到的东西。如果我知道要在 google 上搜索什么答案,我肯定会这样做,但我什至不知道除了我认为我已经理解的 Python OOP 原理之外要搜索什么(我确实复习过)。任何帮助将不胜感激,因为这让我发疯,哈哈。

有帮助吗?

解决方案

他正在将更新后的模型添加到数据库中。模型变了这样 db.session.add() 将更新场景后面的正确行。我不相信 SQLAlchemy 会允许您添加模型的属性,因为它不知道要更新哪一行

也许一个例子会让这一点更清楚。我们采用以下模型:

class User(db.model):
    __tablename__ = 'User'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(25))

现在模型上有 2 个非常重要的属性,用于将其插入/更新到数据库中。表名和id。因此,要使用纯 SQL 将该模型添加到数据库中,我们需要执行以下操作:

INSERT INTO User (name) VALUES ('Some string');

这大致就是您使用时发生的情况 db.session.add() 在一个新的模型上。要更新我们的模型,我们需要执行以下操作:

UPDATE User
SET name='Some other String'
WHERE id=1;

现在,如果您只将模型的一个属性传递给 SQLAlchemy,它如何才能确定您想要添加到哪个表或应该更改哪一行?如果你刚刚通过 self.namedb.session.add() 查询最终看起来像这样:

UPDATE  # There is no way to know the table
SET name='Some other String'
WHERE  ; # There is no way to know which row needs to be changed

如果您尝试的话,SQLAlchemy 很可能会抛出异常。至于为什么它不能从中推导出模型 self 这可能远远超出了 SO 问题的范围。

其他提示

伊恩奥尔德是对的——但我会努力尝试以冗长的方式解释它。

让我们将自己置于 SQLAlchemy 的角色中,并假设我们是 db.session.add 方法。

self.last_seen 是一个 datetime 对象,所以让我们假装我们坐在家里,一个信封从门口进来,地址是 db.session.add. 。太好了,那就是我们,所以我们打开它并阅读上面的消息 2014-07-29 没有其他的。我们知道我们需要将其归档到文件柜中的某个地方,但我们只是没有足够的信息来这样做,我们所知道的是我们有一个 datetime, ,我们不知道什么 User 它属于,或者即使它确实属于 User 归根结底,这只是一个 datetime——我们被困住了。

如果下一个进门的是一个包裹,地址又是: db.session.add, ,然后我们再次打开它——这次它是一个小模型 User, 它有一个名字、一封电子邮件——甚至在它的手臂上还写着最后一次看到的日期时间。现在很容易了——我可以直接去文件柜看看我是否已经把它放在那里了,或者做一些改变以使它们匹配,或者简单地把它归档(如果它是新的)。

这就是区别——使用 ORM 模型,您传递这些完整的用户或产品,或任何周围的东西,并且 SQLALchemy 知道它是一个 db.Model 因此可以通过检查它的详细信息来知道如何以及在哪里处理它。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top