Peewee calls __init__ on model unexpectedly
See original GitHub issueWe’ve run into some trouble when upgrading to peewee 2.8.0, when we have a custom __init__
defined on our models. This behaviour worked fine when on earlier versions (2.7.3 is the other version I tested).
import peewee as pw
db = pw.SqliteDatabase(':memory:')
class TestTable1(pw.Model):
a = pw.IntegerField()
b = pw.IntegerField(default=2)
class Meta:
database = db
class TestTable2(pw.Model):
def __init__(self, a=2):
pw.Model.__init__(self, a=a)
a = pw.IntegerField()
b = pw.IntegerField(default=2)
class Meta:
database = db
db.connect()
db.create_tables([TestTable1, TestTable2])
# This works fine
TestTable1.create(a=2)
t1 = TestTable1.select().get()
# This fails
TestTable2.create(a=2)
t2 = TestTable2.select().get() # Failure with: TypeError: __init__() got an unexpected keyword argument 'b'
In the code above, the failure occurs in the final select, it seems that when the model instance is created, the code in playhouse._speedups._ModelQueryResultWrapper.process_row
uses __init__
to create an instance of the row with the full results of the query passed as kwargs (i.e. a=2, b=2). However, the TestTable2.__init__
does not support b
as a keyword argument.
It’s not clear from the documentation how well I should expect custom __init__
methods to work. However, I would imagine that this could be fixed by making playhouse._speedups._ModelQueryResultWrapper.process_row
explicitly call pw.Model.__init__
on an instance created via __new__
.
Issue Analytics
- State:
- Created 8 years ago
- Comments:13 (4 by maintainers)
Top GitHub Comments
You can still put it in
__init__()
with the caveat that__init__()
is going to be called not just when instantiating objects yourself, but also every time aCar
instance is read from a database cursor. I think you probably could make a classmethod on yourCar
object and use that as a factory for complex logic?Try modifying your
__init__
to: