SQLAlchemy actively applied column defaults
from datetime import datetime | |
from sqlalchemy import Column, DateTime, Integer, Text, func, inspect | |
from sqlalchemy.ext.declarative import as_declarative, declared_attr | |
from sqlalchemy.sql.functions import Function | |
def defaults_included_constructor(instance, **kwds): | |
mapper = inspect(instance).mapper | |
for column in mapper.columns: | |
if (default := column.default) is not None: | |
if not isinstance(default.arg, Function) and not callable(default.arg): | |
attr = mapper.get_property_by_column(column) | |
kwds.setdefault(attr.key, default.arg) | |
for attr, value in kwds.items(): | |
setattr(instance, attr, value) | |
@as_declarative(constructor=defaults_included_constructor) | |
class Base: | |
@declared_attr | |
def __tablename__(cls): | |
return cls.__name__.lower() | |
class User(Base): | |
id = Column(Integer, primary_key=True) | |
name = Column(Text) | |
email = Column(Text) | |
role = Column("role_name", Text, default="user") | |
created_at = Column(DateTime, default=func.now()) | |
updated_at = Column(DateTime, default=datetime.utcnow) | |
def main(): | |
john = User(name="John") | |
assert john.role == "user" | |
assert john.created_at is None | |
assert john.updated_at is None | |
print("John has a default role of 'user', pre-flush") | |
claire = User(name="Claire", role="admin") | |
assert claire.role == "admin" | |
print("Claire has a non-default role of 'admin', pre-flush") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment