为什么在 sqlalchemy db (Flask) 中添加 self 而不是 self.last_seen
-
21-12-2019 - |
题
在此代码中 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.name
到 db.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
因此可以通过检查它的详细信息来知道如何以及在哪里处理它。