Skip to main content

SQLAlchemy extension that provides an easy way to track changes to your database models.

Project description

SQLAudit

SQLAudit is a SQLAlchemy extension that provides an easy way to track changes to your database models. It automatically creates an audit trail of changes made to your models, including the user who made the change, the timestamp of the change.

It is designed to work with SQLAlchemy's ORM and provides a simple way to track changes to your models without having to write custom code for each model. SQLAudit only requires you to decorate your models with the @track_table decorator, and it will automatically track changes to the specified fields.

@track_table(tracked_fields=["name", "email", "user_id"])
class Customer(Base):
    __tablename__ = "customers"

    customer_id: Mapped[int] = mapped_column(
        Integer, primary_key=True, autoincrement=True
    )
    name: Mapped[str] = mapped_column(String)
    email: Mapped[str] = mapped_column(String)
    created_by: Mapped[str] = mapped_column(ForeignKey("users.user_id"))

Notice

This project is in its early stages and is not yet ready for production use.

Quick start

To get started with SQLAudit, you need to install it using pip:

pip install sqlaudit

Follow the steps below to set up and use SQLAudit in your SQLAlchemy application.

This short guide demonstrates how to setup and use SQLAudit.

Step 1: Define your Base and User model

SQLAudit requires access to a SQAlchemy Base class. We will also define a User class which will be used to identify who made which change, and a session factory to create sessions.

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, DeclarativeBase

# Create an in-memory SQLite database
DATABASE_URL = "sqlite:///:memory:"
engine = create_engine(DATABASE_URL, connect_args={"check_same_thread": False})

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)


def get_db():
    """Yield a database session for an in-memory SQLite DB."""
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()


class Base(DeclarativeBase):
    pass


class User(Base):
    __tablename__ = "users"
    user_id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
    name: Mapped[string] = mapped_column()

Step 2: Configure SQLAudit

Set the global configuration using set_audit_config().

from sqlaudit import set_audit_config
from utils.db import engine, get_db  # your db utils

set_audit_config(
    engine=engine, #  SQLAlchemy engine
    Base=Base, # SQLAlchemy Base class defined in Step 1
    session_factory=get_db, # function to get a SQLAlchemy session
    default_user_id_field="user_id", # field in User model to identify user
    user_model=User, # User model defined in Step 1
    user_id_field="user_id", # field in User model to identify user
)

Step 3: Add SQLAudit to your models

To enable auditing for your models use the @track_table decorator. This decorator will automatically track changes to the model and store them in the audit table. There are various options you can pass to the decorator to customize the behavior. The most basic usage only requires a list of strings representing the columns you want to track.

from sqlaudit import track_table
from sqlalchemy import Integer, String

@track_table(tracked_fields=["name", "email", "user_id"])
class Customer(Base):
    __tablename__ = "customers"

    customer_id: Mapped[int] = mapped_column(
        Integer, primary_key=True, autoincrement=True
    )
    name: Mapped[str] = mapped_column(String)
    email: Mapped[str] = mapped_column(String)
    user_id: Mapped[str] = mapped_column(String, nullable=False)

Step 4: Register the SQLAudit hooks

SQLAudit uses two SQLAlchemy events to track changes: before_flush and after_flush. You need to register these hooks to enable auditing.

We will be doing this in a startup function that will be called when the application starts.

if __name__ == "__main__":
    Base.metadata.create_all(engine)

    with next(get_db()) as session:
        register_audit_hooks(session=session)

Step 5: Use the session to make changes

Now you can use the session to make changes to your models. SQLAudit will automatically track these changes and store them in the audit table.

with next(get_db()) as session:
    user = User()
    session.add(user)
    session.commit()

    new_customer = Customer(
        name="John Doe", email="jdoe@example.com", user_id=user.user_id
    )

    session.add(new_customer)

    session.commit()
    print(
        f"Customer {new_customer.customer_id} added with name {new_customer.name} and email {new_customer.email}."
    )

    # We check if the customer is in the database
    customer = (
        session.query(Customer)
        .filter_by(customer_id=new_customer.customer_id)
        .first()
    )

    new_customer2 = Customer(
        name="Jane Doe", email="jane@example.com", user_id=user.user_id
    )

    session.add(new_customer2)

    session.commit()
    print(
        f"Customer {new_customer2.customer_id} added with name {new_customer2.name} and email {new_customer2.email}."
    )

    session.refresh(new_customer2)

    new_customer2.name = "Jane Smith"

    session.commit()

    changes = get_resource_changes(
        model_class=Customer,
        session=session,
        filter_resource_ids=["1,", "2"],
        filter_user_ids=str(user.user_id),
    )

    for change in changes:
        print(change)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

sqlaudit-0.1.1.tar.gz (12.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

sqlaudit-0.1.1-py3-none-any.whl (15.6 kB view details)

Uploaded Python 3

File details

Details for the file sqlaudit-0.1.1.tar.gz.

File metadata

  • Download URL: sqlaudit-0.1.1.tar.gz
  • Upload date:
  • Size: 12.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for sqlaudit-0.1.1.tar.gz
Algorithm Hash digest
SHA256 1975b4cfef7921a9b8ad4692b3c30759d3365c0f01e7fabb16c2843b306924c6
MD5 d996aae3ebd3b1dd6f9323544686e3ef
BLAKE2b-256 93e7576ada0a9a4063aa21875cfdea18fa84b3a8db33995131bd32b954621421

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlaudit-0.1.1.tar.gz:

Publisher: publish.yml on SanderJBouwman/sqlaudit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sqlaudit-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: sqlaudit-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 15.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for sqlaudit-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 e7e3f7baced6e9a7aa5d600a290ebae230fa4f5dbeedfabea4dcf5388c48720d
MD5 6f8d5be6dfa56352db18db4d809ab5a7
BLAKE2b-256 e2e1f3b39e562792e16ebf274d60a0aa7d09fa113fdd5fb2bf8f5a03c5f6e169

See more details on using hashes here.

Provenance

The following attestation bundles were made for sqlaudit-0.1.1-py3-none-any.whl:

Publisher: publish.yml on SanderJBouwman/sqlaudit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page