Event-driven extension for SQLAlchemy that enables listening to database CUD events. This library allows you to react to database changes in real time using a clean, declarative API.
Project description
SQLAlchemy Events
About
Event-driven extension for SQLAlchemy that enables listening to database CUD events. This library allows you to react to database changes in real time using a clean, declarative API.
- Currently supports PostgreSQL only
Installation
$ pip install sqlalchemy-events-lib
Quick start
Define models with enabled event tracking using @with_events
models.py
import uuid
from sqlalchemy import UUID
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy_events import with_events, SaEvent
class Base(DeclarativeBase):
id: Mapped[uuid.UUID] = mapped_column(
UUID, nullable=False, primary_key=True, default=uuid.uuid4
)
@with_events([SaEvent.INSERT, SaEvent.UPDATE, SaEvent.DELETE])
class UserModel(Base):
__tablename__ = 'users'
name: Mapped[str] = mapped_column()
Define event handlers using decorators @sa_insert_handler, @sa_update_handler, @sa_delete_handler
services/handlers.py
from models import UserModel
from sqlalchemy_events import sa_insert_handler
@sa_insert_handler(UserModel)
async def handle_user_insert():
print('User inserted!')
Optional Argument: rows
Handlers can optionally accept a rows argument.
If the parameter is declared in the function signature, it will automatically receive a list of affected row IDs.
from models import UserModel
from sqlalchemy_events import sa_insert_handler
@sa_insert_handler(UserModel)
async def handle_user_insert(rows: list[DB_ID]):
print('Users inserted!', rows)
Output:
Users inserted! ['3310aa38-f555-4c05-a57f-5acae32a0a7b', '6aeba1b0-8e80-4369-8adf-cf967ab7ba7a']
Configure SQLAlchemy async engine
session.py
from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine
from config import DATABASE_URL
engine = create_async_engine(DATABASE_URL)
async_session = async_sessionmaker(engine, expire_on_commit=False, autoflush=False)
Initialize event system and start listening
main.py
import asyncio
from sqlalchemy_events import SQLAlchemyEvents
from models import Base
from session import engine
async def main():
SQLAlchemyEvents(
base=Base,
engine=engine,
autodiscover_paths=['services']
)
while True:
await asyncio.sleep(9999)
if __name__ == '__main__':
asyncio.run(main())
Configuration
SQLAlchemyEvents
The SQLAlchemyEvents class accepts the following parameters:
SQLAlchemyEvents(
base,
engine,
autodiscover_paths,
logger=None
)
Parameters:
- base - SQLAlchemy declarative base class used to discover mapped models.
- engine - SQLAlchemy Engine or AsyncEngine instance.
- autodiscover_paths - List of Python module paths where event handlers are defined.
These modules are automatically imported so that decorators such as
@sa_insert_handler,@sa_update_handler,@sa_delete_handlerare executed. Example:
autodiscover_paths=["services", "app.handlers"]
Important:
All modules containing event handlers must be imported through autodiscover This ensures decorator registration is executed at startup
logger (optional)
A standard Python logging.Logger instance.
If provided, the library will log internal lifecycle events such as:
- successful initialization
- listener startup
- trigger setup
Example:
import logging
logger = logging.getLogger('sqlalchemy_events')
logger.setLevel(logging.INFO)
SQLAlchemyEvents(
base=Base,
engine=engine,
autodiscover_paths=['services'],
logger=logger
)
How it works
- autodiscover_paths modules are imported at startup
- Decorators register event handlers into a global registry
- Triggers send events via LISTEN/NOTIFY
- The library receives notifications and dispatches them to registered handlers
Notes
- Handlers can be both async and regular functions
- Only models registered with @with_events will emit events
- Currently supports LISTEN/NOTIFY
- Ensure handlers are imported via autodiscover_paths, otherwise they will not be registered
Example flow
INSERT INTO/UPDATE/DELETE FROM {table} → DATABASE trigger fires → NOTIFY → Python listener receives event → handler is executed
License
MIT
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sqlalchemy_events_lib-0.2.0.tar.gz.
File metadata
- Download URL: sqlalchemy_events_lib-0.2.0.tar.gz
- Upload date:
- Size: 12.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d4b1cf5b3f8c61af52226ab040943187744d4aa7a6b8eadf6f0447355cb11553
|
|
| MD5 |
7d8db4f0be5cf04087df3cc6b61a457f
|
|
| BLAKE2b-256 |
2d3b363c283fb5a58a4a325e3e05c1befcdcc3b3bc24ae323b96207d10894317
|
File details
Details for the file sqlalchemy_events_lib-0.2.0-py3-none-any.whl.
File metadata
- Download URL: sqlalchemy_events_lib-0.2.0-py3-none-any.whl
- Upload date:
- Size: 15.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.1 {"installer":{"name":"uv","version":"0.11.1","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"22.04","id":"jammy","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7f4f80cd522239d9b38b70667f5e1dc66c2ba3295450c1017054560be34c8cf
|
|
| MD5 |
886da96d98cb164acf0d0b838cdc06ee
|
|
| BLAKE2b-256 |
cbb0ef7727536a20a1952f7bc8521c1800526b83c0f0b418f2fe5a900cd1d7ec
|