Created
October 13, 2020 22:21
-
-
Save edelooff/40043405f304f36cbac8a1838aeb20bf to your computer and use it in GitHub Desktop.
SQLAlchemy actively applied column defaults
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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