在flask-sqlalchemy下的Pandas read_sql数据库引擎

时间:2014-08-07 14:35:40

标签: python pandas flask-sqlalchemy

我正在Flask中编写一个Web应用程序,我正在使用pandas从MySQL数据库中检索数据。以下用于工作,使用我从另一篇文章中读到的内容:

db = SQLAlchemy()
app = Flask(__name__)
app.config.from_object(config['default'])
db.init_app(app)
conn = db.engine.connect().connection

然后在视图函数中(在相同的.py文件中):

@app.route('/report', methods=['GET', 'POST'])
def report():
    form = ReportForm()
...
    sql = '''SELECT * FROM availability ...'''
    df = psql.read_sql(sql, conn)
...

    return render_template('report.html', form=form, df=df)

此网页显示基于所选日期间隔的表格(来自表格)。 我通过x-editable在网页上添加了此表的内联编辑,我看到更改已发布到数据库,但如果我再次提交表单,则表只会在更改之前加载旧数据。我只是在重新打开网页后看到了这些变化,这很奇怪。

移动' conn' read_sql工作之前的行:

sql = '''SELECT * FROM availability ...'''
conn = db.engine.connect().connection
df = psql.read_sql(sql, conn)

但这并不好,因为我必须为每个查询重复此操作(并且每个视图都有一些查询)。有没有办法我只是在开始时声明这个连接对象一次并将其结束? SQLAlchemy的ORM可以工作,但我更喜欢在这种情况下编写原始SQL。

编辑:

里斯'建议适用于一个查询,但现在我遇到了另一个错误:

File "C:\Users\KF\flask-test\hello.py", line 107, in report
df = pd.read_sql_query(sql.format(vd='20140727', sd=sd, ed=ed), db.engine)
File "C:\Anaconda\envs\lightson\lib\site-packages\pandas\io\sql.py", line 363, in read_sql_query
parse_dates=parse_dates)
File "C:\Anaconda\envs\lightson\lib\site-packages\pandas\io\sql.py", line 823, in read_sql
result = self.execute(*args)
File "C:\Anaconda\envs\lightson\lib\site-packages\pandas\io\sql.py", line 810, in execute
return self.engine.execute(*args, **kwargs)
File "C:\Anaconda\envs\lightson\lib\site-packages\sqlalchemy\engine\base.py", line 1752, in execute
return connection.execute(statement, *multiparams, **params)
File "C:\Anaconda\envs\lightson\lib\site-packages\sqlalchemy\engine\base.py", line 721, in execute
return self._execute_text(object, multiparams, params)
File "C:\Anaconda\envs\lightson\lib\site-packages\sqlalchemy\engine\base.py", line 870, in _execute_text
statement, parameters
File "C:\Anaconda\envs\lightson\lib\site-packages\sqlalchemy\engine\base.py", line 958, in _execute_context
context)
File "C:\Anaconda\envs\lightson\lib\site-packages\sqlalchemy\engine\base.py", line 1163, in _handle_dbapi_exception
util.reraise(*exc_info)
File "C:\Anaconda\envs\lightson\lib\site-packages\sqlalchemy\engine\base.py", line 951, in _execute_context
context)
File "C:\Anaconda\envs\lightson\lib\site-packages\sqlalchemy\engine\default.py", line 436, in do_execute
cursor.execute(statement, parameters)
File "c:\users\kf\appdata\local\temp\easy_install-_444w8\MySQL_python-1.2.5-py2.7-win-amd64.egg.tmp\MySQLdb\cursors.py", line 187, in execute
query = query % tuple([db.literal(item) for item in args])
TypeError: not enough arguments for format string

但原始的sql字符串很好 - 我自己运行查询并且有效。实际SQL:

sql = '''SELECT * FROM availability WHERE view_date = str_to_date('{vd}', '%Y%m%d') and book_date >= str_to_date('{sd}','%Y%m%d') and book_date <= str_to_date('{ed}', '%Y%m%d')'''

这里&#39; sd&#39;并且&#39; ed&#39;字符串看起来像&#39; 20140801&#39;。看起来我必须逃避MySQL的那些问题,但我似乎无法找到办法。

编辑:

让它发挥作用。添加另一个&#39;%&#39;在&#39;%Y&#39;,&#39;%m&#39;前面和&#39;%d&#39;逃避百分号。 基本上,正如joris所说,使用pd.read_sql_query,你应该没事。

1 个答案:

答案 0 :(得分:5)

想出来。对于那些将来可能需要它的人: 1.在'%Y','%m'和'%d'前添加另一个'%'以逃避百分号。 2.像joris所说,使用pd.read_sql_query代替read_sql