我是Flask和SQLAlchemy的新手(过去3年一直与Django合作)。我需要调用现有的 PostgreSQL函数,该函数写入数据库中的3个不同的表。这是我无法控制的(我只需要让它工作)。该函数返回一条记录(自定义Postgres类型),其中包含有关结果的信息。这是代码:
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()
上面的代码运行没有错误。从日志消息中,我可以看到从数据库返回正确的数据。但是,如果我去psql,我看不到新插入的数据。似乎事务从未真正提交过。
我能找到的大多数文档和示例都基于使用SQLAlchemy的ORM。我在这里做错了什么?
堆栈信息:
Flask==0.10.1
Flask-SQLAlchemy==1.0
psycopg2==2.5.2
Python 2.7.3
Postgresql 9.3
更新
我找到了一种方法让它起作用,这是一个实际适用于我的样本:
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()
我已经回顾了SQLAlchemy的connect方法中的代码。似乎调用“connect()”只是从池中获取一个新连接(默认情况下似乎设置为size = 5 - 至少我没有将它设置为5)。所以,我不确定它是否有太大的危害。但是,似乎应该通过使原始问题中的示例工作来使代码更清晰。我仍然希望有人能告诉我该怎么做。
答案 0 :(得分:1)
如果您在SQLAlchemy中使用原始SQL,那么我认为您必须自己发出BEGIN和COMMIT语句。尝试添加以下内容:
...
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;')
...