SQLAlchemyでcreated_at, updated_atを共通化する
https://docs.sqlalchemy.org/en/13/orm/extensions/declarative/mixins.html
Mixinを使えば可能?
base.py
from sqlalchemy import Column, DateTime
from datetime import datetime
class TimestampMixin(object):
created_at = Column(DateTime, default=datetime.now(), nullable=False)
updated_at = Column(
DateTime, default=datetime.now(), onupdate=datetime.now(), nullable=False
)
articles.py
from sqlalchemy import Column, Integer, String
from .base import TimestampMixin
from ..db.engine import Base
class Article(Base, TimestampMixin):
__tablename__ = "articles"
id = Column(Integer, primary_key=True, index=True)
title = Column(String)
slug = Column(String, unique=True, index=True)
description = Column(String)
body = Column(String)
この方法だと実現できるが、DDLを見てみるとカラムが最初に作られてしまっていた。
CREATE TABLE articles (
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
id SERIAL NOT NULL,
title VARCHAR,
slug VARCHAR,
description VARCHAR,
body VARCHAR,
PRIMARY KEY (id)
)
SQLAlchemyを簡単にまとめてみた(TIPSもあるよ) - Qiita
そんなときは@declared_attr
を使うといいらしい
from sqlalchemy import Column, DateTime
from sqlalchemy.ext.declarative import declared_attr
from datetime import datetime
class TimestampMixin(object):
@declared_attr
def created_at(cls):
return Column(DateTime, default=datetime.now(), nullable=False)
@declared_attr
def updated_at(cls):
return Column(
DateTime, default=datetime.now(), onupdate=datetime.now(), nullable=False
)
生成したDDLを見て見ると意図したとおりに最後に来ている
CREATE TABLE articles (
id SERIAL NOT NULL,
title VARCHAR,
slug VARCHAR,
description VARCHAR,
body VARCHAR,
created_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
updated_at TIMESTAMP WITHOUT TIME ZONE NOT NULL,
PRIMARY KEY (id)
)