Stay Hungry,Stay Foolish!

mysqlalchemy table operation audit

mysqlalchemy audit extension

https://sqlalchemy-declarative-extensions.readthedocs.io/en/stable/audit_tables.html

from sqlalchemy import Column, types
from sqlalchemy.orm import declarative_base

from sqlalchemy_declarative_extensions import declarative_database
from sqlalchemy_declarative_extensions.audit import audit

Base = declarative_database(declarative_base())


@audit()
class Foo(Base):
    __tablename__ = "foo"

    id = Column(types.Integer(), primary_key=True)
    name = Column(types.Unicode())
    json = Column(JSONB())


audit_table = Foo.__audit_table__

 

change

foo1 = Foo(id=1, name=None, json=None)
foo2 = Foo(id=2, name='wat?', json={})
pg.add(foo1)
pg.add(foo2)
pg.commit()

foo1.name = 'wow!'
pg.delete(foo2)
pg.commit()

 

audit table

 

sqlalchemy-continuum

https://github.com/kvesteri/sqlalchemy-continuum

https://sqlalchemy-continuum.readthedocs.io/en/latest/intro.html

 

Features

    Creates versions for inserts, deletes and updates
    Does not store updates which don't change anything
    Supports alembic migrations
    Can revert objects data as well as all object relations at given transaction even if the object was deleted
    Transactions can be queried afterwards using SQLAlchemy query syntax
    Query for changed records at given transaction
    Temporal relationship reflection. Version object's relationship show the parent objects relationships as they where in that point in time.
    Supports native versioning for PostgreSQL database (trigger based versioning)

 

from sqlalchemy_continuum import make_versioned
from sqlalchemy import Column, Integer, Unicode, UnicodeText, create_engine
from sqlalchemy.orm import create_session, configure_mappers, declarative_base

make_versioned(user_cls=None)

Base = declarative_base()
class Article(Base):
    __versioned__ = {}
    __tablename__ = 'article'
    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(Unicode(255))
    content = Column(UnicodeText)

configure_mappers()
engine = create_engine('sqlite://')
Base.metadata.create_all(engine)
session = create_session(bind=engine, autocommit=False)

article = Article(name=u'Some article', content=u'Some content')
session.add(article)
session.commit()
article.versions[0].name
article.name = u'Updated name'
session.commit()
article.versions[1].name
article.versions[0].revert()
article.name

 

posted @ 2024-04-28 13:54  lightsong  阅读(4)  评论(0编辑  收藏  举报
Life Is Short, We Need Ship To Travel