Reputation: 23
I have a User model like this:
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(64), unique=True, index=True
# ...
def __init__(self, **kwargs):
pass
When the instance is created like:user = User(username='john')
, the constructor is called successfully.
But if the instance is returned by user = User.query.filter_by(username=john).first()
, the constructor won't be called anyway.
And I have checked that the instance returned by the query is an instance of User, so the constructor should be called when the query is done. Because to my understanding, the constructor is called every time when an instance is created.
The question is: why this happens and what to do to call __init__
when the user is returned by the query.
Upvotes: 1
Views: 384
Reputation: 9739
I just ran accross this same problem (constructor not being called), and reading through SQLAlchemy documentation, that's exactly how it's supposed to behave. When an instance is being created from a Query
object, it doesn't call the __init__
method. Instead, it calls methods marked as reconstructor
(decorator).
To mark a method as reconstructor, declare a parameterless method and decorate it with the method from your SQLAlchemy
instance:
class User(UserMixin, db.Model):
@db.reconstructor
def reload(self):
# Will be run when loading from a Query object
From the documentation:
Any method may be tagged as the
reconstructor()
, even the__init__
method. SQLAlchemy will call the reconstructor method with no arguments.
So, if your class has initialization code, or if you call super()
, you can call your reconstructor from your __init__
:
class User(UserMixin, db.Model):
def __init__(self, **kwargs):
super(User, self).__init__(**kwargs)
self.reload()
@db.reconstructor
def reload(self):
# Process data from model
That way, reload()
will be called upon custom initialization and when queried.
Upvotes: 3