Why isn't SQLAlchemy default column value available before object is committed?
default-value, python, sqlalchemy
Solution
You can use `force_instant_defaults` listener from `sqlalchemy_utils` to change this behavior:
from sqlalchemy_utils import force_instant_defaults
force_instant_defaults()
class TestModel(Base):
__tablename__ = 'tmodel'
id = sa.Column(sa.Integer, primary_key=True)
foo = sa.Column(sa.Integer, default=0)
model = TestModel()
assert model.foo == 0
Problem
Recently I figured out that SQLAlchemy's Column default doesn't work as I expect it to: ``` >>> Base = declarative_base() >>> class TestModel(Base): ... __tablename__ = 'tmodel' ... id = sa.Column(sa.Integer, primary_key=True) ... foo = sa.Column(sa.Integer, default=0) ... >>> tmodel_instance = TestModel() >>> print tmodel_instance.foo None >>> session.add(tmodel_instance) >>> print tmodel_instance.foo None >>> session.commit() >>> print tmodel_instance.foo 0 ``` I want `tmodel_instance.foo` to equal `0` right after object instantiation, but it seems that the default value is only used when executing `INSERT` command, and it really confuses me. Why would one prefer the `default` over `server_default`? And how do I achieve what I want? Am I supposed to specify all default arguments in `__init__`? That seems to be code duplication: to change the default value I have to change it twice and maintain those values equality -- is there some way to avoid that?