question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Trying to replacing SQLAlchemy-Continuum

See original GitHub issue

I’m trying to replace SQLAlchemy-Continuum in my project with postgresql-audit but must be missing something.

When I replace the call to make_versioned with versioning_manager.init(Base) and try and create the schema it tries to use the audit_table function before it’s defined.

Traceback (most recent call last):
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 507, in do_execute
    cursor.execute(statement, parameters)
psycopg2.ProgrammingError: function audit_table(unknown) does not exist
LINE 1: SELECT audit_table('company') AS audit_table_1
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "populate.py", line 30, in <module>
    database_manager.create_schema()
  File "/Users/dereklambert/Development/audit-tools3/audit_tools/manager/database_manager.py", line 88, in create_schema
    Base.metadata.create_all(self.engine)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/sql/schema.py", line 4004, in create_all
    tables=tables)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1940, in _run_visitor
    conn._run_visitor(visitorcallable, element, **kwargs)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1549, in _run_visitor
    **kwargs).traverse_single(element)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/sql/visitors.py", line 121, in traverse_single
    return meth(obj, **kw)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/sql/ddl.py", line 757, in visit_metadata
    _is_metadata_operation=True)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/sql/visitors.py", line 121, in traverse_single
    return meth(obj, **kw)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/sql/ddl.py", line 810, in visit_table
    _is_metadata_operation=_is_metadata_operation)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/event/attr.py", line 284, in __call__
    fn(*args, **kw)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/postgresql_audit/base.py", line 33, in __call__
    bind.execute(self.stmt)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 948, in execute
    return meth(self, multiparams, params)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
    compiled_sql, distilled_params
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1200, in _execute_context
    context)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1413, in _handle_dbapi_exception
    exc_info
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 186, in reraise
    raise value.with_traceback(tb)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
    context)
  File "/Users/dereklambert/Development/audit-tools3/venv/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 507, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) function audit_table(unknown) does not exist
LINE 1: SELECT audit_table('company') AS audit_table_1
               ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
 [SQL: 'SELECT audit_table(%(audit_table_2)s) AS audit_table_1'] [parameters: {'audit_table_2': 'company'}] (Background on this error at: http://sqlalche.me/e/f405)

I decided to try something simple to test the functionality, but no activity records are saved (similar to #26)

import sqlalchemy as sa
import sqlalchemy.orm as orm
import sqlalchemy_utils as utils
from sqlalchemy.ext.declarative import declarative_base
from postgresql_audit import VersioningManager


Base = declarative_base()

versioning_manager = VersioningManager()
versioning_manager.init(Base)


class Role(Base):
    name        = sa.Column(sa.String, primary_key=True)
    description = sa.Column(sa.String)

    __tablename__ = 'role'
    __versioned__ = {}


engine_url = 'postgresql+psycopg2://postgres@localhost/pyaudit'

if utils.database_exists(engine_url):
    utils.drop_database(engine_url)

utils.create_database(engine_url)

engine = sa.create_engine(engine_url, echo=True)

Base.metadata.create_all(engine)

session = orm.sessionmaker(bind=engine)()

role = Role(name='test')
session.add(role)
session.commit()

Activity = versioning_manager.activity_cls

activity = session.query(Activity).first()
print(activity)

I’d really like to get this working so I can test the performance against SQLAlchemy-Continuum before putting my project into production. I presume it’ll be difficult to migrate after the fact.

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:1
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
djlambertcommented, Apr 29, 2018

Did some digging through the tests and added the following code before creating all the tables:

orm.configure_mappers()

versioning_manager.transaction_cls.__table__.create(engine)
versioning_manager.activity_cls.__table__.create(engine)

This seems to have fixed the issue. Is this something missing from the documentation?

0reactions
k-dalcommented, Aug 25, 2019

It’s hard to be sure without more context, but I did notice one particularly important omission in the snippets above: versioning_manager.init(Base)

There’s more info on the SQLAlchemy integration here: https://postgresql-audit.readthedocs.io/en/stable/sqlalchemy.html - I found it pretty useful as a basic reference.

Read more comments on GitHub >

github_iconTop Results From Across the Web

API Documentation — SQLAlchemy-Continuum 1.3.6 ...
Remove listeners from specified mapper that track SQL inserts, updates and deletes. Parameters: mapper – mapper to remove the SQL operations tracking listeners ......
Read more >
sqlalchemy-continuum(1) - Arch manual pages
SQLAlchemy -Continuum is a versioning extension for SQLAlchemy. ... When changing entities and committing results into database Continuum saves the used ...
Read more >
SqlAlchemy Continuum: history and transaction tables are not ...
You have to create the table before use sqlalchemy-continuum . You can create the table via script, create it with db.create_all() or ...
Read more >
SQLAlchemy-Continuum - PyPI
SQLAlchemy -Continuum 1.3.13. pip install SQLAlchemy-Continuum Copy PIP instructions. Latest version. Released: Sep 6, 2022. Versioning and auditing ...
Read more >
Adding versioning to Flask-SQLAlchemy with ... - JSS
SQLAlchemy has a limited versioning extension that does not support entire transactions. SQLAlchemy-Continuum offers a flexible API for implementing a ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found