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

tan*_*ius 0 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
Run Code Online (Sandbox Code Playgroud)

然后在视图函数中(在相同的.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)
Run Code Online (Sandbox Code Playgroud)

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

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

sql = '''SELECT * FROM availability ...'''
conn = db.engine.connect().connection
df = psql.read_sql(sql, conn)
Run Code Online (Sandbox Code Playgroud)

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

编辑:

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

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
Run Code Online (Sandbox Code Playgroud)

但是原始的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')'''
Run Code Online (Sandbox Code Playgroud)

这里's'和'ed'是看起来像'20140801'的字符串.看起来我必须逃避MySQL的'%',但我似乎无法找到办法.

编辑:

得到它的工作.在'%Y','%m'和'%d'前面添加另一个'%'以转义百分号.基本上,正如joris所说,使用pd.read_sql_query,你应该没事.

tan*_*ius 5

弄清楚了.对于那些将来可能需要这个的人:1.在'%Y','%m'和'%d'前添加另一个'%'以逃避百分号.2.像约里斯所说,用pd.read_sql_query而不是read_sql.