在此代码中,只要用户使用该站点,就会使用当前时间刷新last_seen
字段。但是,在调用db时,他(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)
看起来非常简单,我确信它是,但显然我错过了一些东西,或者没有学到我应该学到的东西。如果我知道谷歌的答案,我肯定会这样做,但我甚至不确定除了Python OOP的主要内容之外还要搜索什么,我认为我已经理解了(我做了回顾)。任何帮助将不胜感激,因为这让我发疯,哈哈。
答案 0 :(得分:1)
他正在将更新的模型添加到数据库中。模型已更改,因此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将该模型添加到DB,我们需要执行以下操作:
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问题范围的模型。
答案 1 :(得分:0)
IanAuld是对的 - 但我会努力尝试以冗长的方式解释它。
让我们自己处理SQLAlchemy的角色,并假装我们是db.session.add
方法。
self.last_seen
是一个datetime
对象,所以我们假装我们坐在家里,一个信封通过门进入db.session.add
。太好了,那就是我们,所以我们打开它,阅读刚才说2014-07-29
的消息。我们知道我们需要在文件柜中的某处提交它,但我们没有足够的信息这样做,我们都知道我们有一个datetime
,我们不知道是什么{ {1}}它属于,或者即使它确实属于User
,它只是User
- 我们被卡住了。
如果相反,通过门的下一件事是一个包裹,再次发送到datetime
,我们再打开它 - 这次它是一个db.session.add
的小模型,它有一个名字,电子邮件 - 甚至是写在它上面的最后一个日期时间。现在很容易 - 我可以直接进入文件柜,看看我是否已经把它放在那里,并且要么进行一些修改以使它们匹配,要么简单地将它们放在一起如果它是新的。
这就是区别 - 对于ORM模型,你传递这些完整的用户或产品,或者任何东西,并且SQLALchemy知道它是User
,因此可以知道如何以及在何处处理它检查它的细节。