6

I'm a newbie to Flask and SQLAlchemy (been working with Django for the last 3 years). I need to call an existing PostgreSQL function that writes to 3 different tables in a database. This is out of my control (I just have to make it work). The function returns a record (custom Postgres type) with information about the results. Here is the code:

from flask.ext.sqlalchemy import SQLAlchemy

db = SQLAlchemy()

...

retval = db.engine.execute(
    'SELECT * FROM add_purchase(%s, %s, %s, %s, %s, %s, %s);',
    clean_data.account_id, amount, tax, deposit, clean_data.pos_id, 
    g.token_id, clean_data.external_reference_id).first()

app.logger.info(retval) # for debugging

db.session.commit()

The above code runs without error. From the log message, I can see the the correct data is getting returned from the database. However, if I go to psql, I cannot see the newly inserted data. It would seem that the transaction is never actually committed.

Most of the documentation and examples I can find are based on using SQLAlchemy's ORM. What am I doing wrong here?

Stack info:

Flask==0.10.1
Flask-SQLAlchemy==1.0
psycopg2==2.5.2
Python 2.7.3
Postgresql 9.3

Update

I have figured out a way to make it work, here is a sample that actually works for me:

from sqlalchemy import exc

...

connection = db.engine.connect()
trans = connection.begin()
try:
    retval = connection.execute(
        'SELECT * FROM add_purchase(%s, %s, %s, %s, %s, %s, %s);',
        clean_data.account_id, amount, tax, deposit,
        clean_data.pos_id, g.token_id,
        clean_data.external_reference_id).first()
except exc.SQLAlchemyError:
    trans.rollback()
    raise
else:
    trans.commit()

And I've reviewed the code in SQLAlchemy's connect method. It seems like calling "connect()" just gets a new connection from the pool (which seem to be set to size=5 by default - at least I'm not setting it to 5). So, I'm not sure if there is much harm in it. However, it seems like there should be away to make this code cleaner by making the example in the original question work. I'm still hoping someone can tell me how to do that.

1 Answer 1

1

If you are using raw SQL with SQLAlchemy, then I think you have to issue the BEGIN and COMMIT statements yourself. Try adding something like this:

...
begin_retval = db.engine.execute('BEGIN;')
retval = db.engine.execute('SELECT * FROM add_purchase(%s, %s, %s, %s, %s, %s, %s);',
clean_data.account_id, amount, tax, deposit, clean_data.pos_id, 
g.token_id, clean_data.external_reference_id).first()
commit_retval = db.engine.execute('COMMIT;')
...
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much for your reply. I've tred that exact code and it does not commit the transacton. It doesn't raise an error either.
Hmm. So how does add_purchase work? Do you have the code for that? That might be helpful...
Yes; please see original question. "The above code runs without error. From the log message, I can see the the correct data is getting returned from the database."

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.