LoginSignup
8
3

More than 1 year has passed since last update.

SQLAlchemyでcreated_at, updated_atを共通化する

Posted at

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)
)
8
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3