kvesteri / postgresql-audit

Audit trigger for PostgreSQL
BSD 2-Clause "Simplified" License
126 stars 28 forks source link

Not working with Postgres 9.4.5 or 9.5.1 #21

Closed late-warrior closed 7 years ago

late-warrior commented 7 years ago

Hi,

What versions of Postgres is the library known to work with ? I tried against 9.4.5 and 9.5.1 with no success. I see all the user defined functions and triggers being created but there is no entry being made in either the transaction or the activity table.

from postgresql_audit import versioning_manager
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
Session = sessionmaker()
SQLALCHEMY_DATABASE_URI = 'postgresql://user:password@database-url:5432/db'
e = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)
Base = declarative_base(bind=e)

versioning_manager.init(Base)

class Article(Base):
    __tablename__ = 'article'
    __versioned__ = {}
    id = Column(Integer, primary_key=True)
    name = Column(String)

if __name__ == '__main__':
    session = Session(bind=e)
    Base.metadata.create_all(e, checkfirst=True)
    article = Article(name='Some other article here')
    session.add(article)
    session.commit()
jacobsvante commented 7 years ago

This took me a while to figure out. By looking at conftest.py I figured out that you have to call sa.orm.configure_mappers() and create the tables manually. See my modified version of your code below.

@kvesteri Can you expand on why these have to be called? Can't remember that this was the case before, but I haven't meddled with the project in a while so I'm a bit rusty 😅

Perhaps there's some way this can be made more user friendly?

import sqlalchemy as sa

from postgresql_audit import versioning_manager
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
Session = sessionmaker()
SQLALCHEMY_DATABASE_URI = 'postgres://localhost/postgresql_audit_test2'
e = create_engine(SQLALCHEMY_DATABASE_URI, echo=True)
Base = declarative_base(bind=e)

versioning_manager.init(Base)

class Article(Base):
    __tablename__ = 'article'
    __versioned__ = {}
    id = Column(Integer, primary_key=True)
    name = Column(String)

if __name__ == '__main__':
    session = Session(bind=e)
    sa.orm.configure_mappers()  # <-- Important
    versioning_manager.transaction_cls.__table__.create(e)  # <-- Important
    versioning_manager.activity_cls.__table__.create(e)  # <-- Important
    Base.metadata.create_all(e, checkfirst=True)
    article = Article(name='Some other article here')
    session.add(article)
    session.commit()
    print(session.query(versioning_manager.activity_cls).all())  # <-- Verify!
kvesteri commented 7 years ago

The reason for that is that there are after_configuration listeners that get fired with mapper_configured call. As for the other matter... yes it could definitely be more user friendly :) PRs welcome!