Default value no work in Model.insert().execute() #107

Closed
zffl opened this Issue Sep 9, 2012 · 7 comments

Comments

Projects
None yet
3 participants

zffl commented Sep 9, 2012

I add default value for datetime field, but not work in this case, but It work by writing m =Model(..); m.save(). Is this a problem or by design?

Owner

coleifer commented Sep 9, 2012

When you initialize a model instance, it will initialize fields to their default values, e.g.:

>>> from tests import *
>>> dv = DefaultVals() # <-- pub date defaults to datetime.datetime.now
>>> dv.pub_date
datetime.datetime(2012, 9, 9, 11, 31, 37, 797693)

When you call save() it rounds up all the field values on the instance and passes them along to the insert query.

However when using insert directly it will only use the values you pass in explicitly. This is not explicitly by design. I'll have to think on whether to keep the current behavior (insert is explicit and ignores defaults) or whether it will implicitly fill in missing values with the field defaults.

@coleifer coleifer closed this in c102866 Sep 9, 2012

Owner

coleifer commented Sep 9, 2012

Insert will now respect defaults when they are not specified

phryk commented Sep 5, 2016

I think this fix might have been un-fixed.

m = DatModel()
m.foo = None
m.save()

This results in an Integrity error (NOT NULL constraint failed) if DatModel.foo has null=False.

I already found out that in the current version in pip, nothing besides Model.__init__ calls ModelOptions.get_default_dict (The fix introduced a call to it in InsertQuery.__init__).

Owner

coleifer commented Sep 5, 2016

I'm not sure I'm understanding correctly, because if you explicitly set foo to None, peewee will not override it. Given that, makes sense to me there would follow an exception if foo was not null.

Owner

coleifer commented Sep 5, 2016

Oh, but I see your point in reference to this particular issue and the way it was resolved.

So, to clarify, the fix should still be in place. Check out InsertQuery._iter_rows(). Basically it's applying defaults there. But when you are working with a model and explicitly set a field to a value, that takes precedence over a default.

phryk commented Sep 6, 2016

Thanks for the clarification. But now I'm wondering what the correct way of setting the value of a field (of a previously existing instance, so UPDATE) back to its default. Do I have to manually evaluate DatModel.datfield._meta.default or is there a way to make peewee do it?

Owner

coleifer commented Sep 7, 2016

Just do: obj.field = ModelClass.field.default (add parentheses if it's a callable).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment