In this code the last_seen
field is being refreshed with the current time whenever the user uses the site. However, in the call to the db, he (Minuel Grindberg "Flask Web Development") adds self
instead of self.last_seen
, which confuses me. I understand what the basic principals of OOP are, and I (thought) understand what self
is (reference to the object being created), but I do NOT understand why we don't add self.last_seen
in the last line db.session.add(self)
? Full code below. . .
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)
Looks very simple and I'm sure it is, but obviously I'm missing something, or haven't learned something I should have. If i knew what to google for an answer, I would have certainly done so, but I'm not even sure what to search for other than the principals of Python OOP which I thought I already understood (I did review). Any help would be greatly appreciated because this is driving me crazy, lol.
He is adding the updated model to the DB. The model changed so db.session.add()
will update the proper row behind the scene. I don't believe SQLAlchemy would allow you to add on the property of model because it wouldn't know which row to update
Perhaps an example would make this clearer. Let's take the following model:
class User(db.model):
__tablename__ = 'User'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(25))
Now there are 2 very important attributes on the model for inserting/updating it in the DB. The table name and the id. So to add that model to the DB with plain SQL we would need to do something like:
INSERT INTO User (name) VALUES ('Some string');
This is roughly what happens when you use db.session.add()
on a new model. To update our model we would need to do something like:
UPDATE User
SET name='Some other String'
WHERE id=1;
Now if you were to only pass one attribute of a model to SQLAlchemy how would it be able to figure out what table you wanted to add to or which row was supposed to get changed?
If you just passed self.name
to db.session.add()
the query would end up looking like this:
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 would most likely throw an exception if you tried. As for why it can't deduce the model from self
that is probably way outside the scope of an SO question.