Skip to content

Instantly share code, notes, and snippets.

@edelooff
Created October 13, 2020 22:21
Show Gist options
  • Save edelooff/40043405f304f36cbac8a1838aeb20bf to your computer and use it in GitHub Desktop.
Save edelooff/40043405f304f36cbac8a1838aeb20bf to your computer and use it in GitHub Desktop.
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