Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Record queries errors on some Postgres queries #1261

Open
stl-gilesbartonowen opened this issue Sep 30, 2023 · 0 comments
Open

Record queries errors on some Postgres queries #1261

stl-gilesbartonowen opened this issue Sep 30, 2023 · 0 comments

Comments

@stl-gilesbartonowen
Copy link

Although the flask documentation claims it passes ExecutionContext objects optionally, it appears it sometimes passes PGExecutionContext_psycopg2 objects, which are not guaranteed to have a .statement attribute. This means that line 111 in record_queries.py will throw the following:

  File <FILE>, line 41, in <FN>
    return context.fire_sequence(model_id_seq, None)
  File "/usr/local/webapp/flask/lib/python3.8/site-packages/sqlalchemy/dialects/postgresql/base.py", line 2837, in fire_sequence
    return self._execute_scalar(
  File "/usr/local/webapp/flask/lib/python3.8/site-packages/sqlalchemy/engine/default.py", line 1658, in _execute_scalar
    conn._cursor_execute(self.cursor, stmt, parameters, context=self)
  File "/usr/local/webapp/flask/lib/python3.8/site-packages/sqlalchemy/engine/base.py", line 2189, in _cursor_execute
    self.dispatch.after_cursor_execute(
  File "/usr/local/webapp/flask/lib/python3.8/site-packages/sqlalchemy/event/attr.py", line 487, in __call__
    fn(*args, **kw)
  File "/usr/local/webapp/flask/lib/python3.8/site-packages/sqlalchemy/event/attr.py", line 174, in wrap_kw
    return fn(**argdict)
  File "/usr/local/webapp/flask/lib/python3.8/site-packages/flask_sqlalchemy/record_queries.py", line 111, in _record_end
    statement=context.statement,
sqlalchemy.exc.StatementError: (builtins.AttributeError) 'PGExecutionContext_psycopg2' object has no attribute 'statement'

I appreciate this is somewhat an issue with Flask but I think this can be handled in a safe way within flask-alchemy, especially given when these contexts are passed in they don't actually have the fired sequence sql in, but rather the broader insert. The listener functions are called with "statement" as a kwarg so I think there's a strong argument to use that primarily.

This is the case I've found so far:

from sqlalchemy.sql  import Sequence

db = SQLAlchemy()

field_sequence = Sequence("field_sequence")

def get_default_field(context):
    if context.get_current_parameters()['set_field']:
        return context.fire_sequence(field_sequence, None)

class MyModel(db.Model):
    set_field = db.Column(db.Boolean)
    field = db.Column(db.BigInteger, default=get_default_field, nullable=True)


m = MyModel(set_field=True)
db.session.add(m)
db.session.flush()

Environment:

  • Python version: 3.8.16
  • Flask-SQLAlchemy version: 3.1.1
  • Flask version: 2.3.3
  • SQLAlchemy version: 2.0.21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant