How to apply Column defaults before a commit in sqlalchemy

python, sqlalchemy

Solution

The column default only applies to INSERT and UPDATE statements, and thus isn't being applied until you `.flush()` the session.

To see the same value on new instances before you flush, you need to apply the default when a new instance is being created; in the `__init__` method of the `User` object:

class User(Base):
    __tablename__ = 'users'

    def __init__(self, **kwargs):
        if 'money' not in kwargs:
             kwargs['money'] = self.__table__.c.money.default.arg
        super(User, self).__init__(**kwargs)

    id = Column(Integer, primary_key=True)
    money = Column(Integer, default=100)

If no `money` attribute is being set, we add one directly based on the default configured for the column.

Note that the defaults are SQL expressions, not Python values, so you may have to map those to Python objects first. For example, a boolean field will have a default `'false'` or `'true'` string value, not a `False` or `True` Python boolean object.

Problem

I have a declarative-base model: ``` class User(Base): id = Column(Integer, primary_key=True) money = Column(Integer, default=100) ``` and then I run ``` >>> u = User() >>> u.money None ``` How can I populate the defaults using sqlalchemy without writing anything to the database?

Original source

Related problems