Pandas read_sql с параметрами
Есть ли примеры того, как передавать параметры с помощью SQL-запроса в Pandas?
В частности, я использую механизм SQLAlchemy для подключения к базе данных PostgreSQL. До сих пор я обнаружил, что следующие работы:
df = psql.read_sql(('select "Timestamp","Value" from "MyTable" '
'where "Timestamp" BETWEEN %s AND %s'),
db,params=[datetime(2014,6,24,16,0),datetime(2014,6,24,17,0)],
index_col=['Timestamp'])
Документация Pandas гласит, что параметры также могут передаваться как dict, но я не могу заставить это работать, например, попробовав:
df = psql.read_sql(('select "Timestamp","Value" from "MyTable" '
'where "Timestamp" BETWEEN :dstart AND :dfinish'),
db,params={"dstart":datetime(2014,6,24,16,0),"dfinish":datetime(2014,6,24,17,0)},
index_col=['Timestamp'])
Каков рекомендуемый способ запуска этих типов запросов из Pandas?
Ответы
Ответ 1
read_sql
docs говорят, что этот аргумент params
может быть списком, кортежем или dict (см. docs).
Чтобы передать значения в запросе sql, возможны разные синтаксисы: ?
, :1
, :name
, %s
, %(name)s
(см. PEP249).
Но не все эти возможности поддерживаются всеми драйверами баз данных, , поддержка которых зависит от драйвера, который вы используете (psycopg2
в вашем случае, я полагаю).
В вашем втором случае при использовании dict вы используете "именованные аргументы", и согласно документации psycopg2
они поддерживают стиль %(name)s
(и, следовательно, не :name
, я полагаю), см. http://initd.org/psycopg/docs/usage.html#query-parameters.
Поэтому использование этого стиля должно работать:
df = psql.read_sql(('select "Timestamp","Value" from "MyTable" '
'where "Timestamp" BETWEEN %(dstart)s AND %(dfinish)s'),
db,params={"dstart":datetime(2014,6,24,16,0),"dfinish":datetime(2014,6,24,17,0)},
index_col=['Timestamp'])
Ответ 2
Я использую эту настройку с SQLite, что означает, что я могу обрабатывать параметры в Python, а не в Pandas в частности. Хорошо работает для меня и легче читать, а затем напрямую бросает запрос и параметры в read_sql.
con = sqlite3.connect("mydb.db")
verses_sql = '''SELECT
kjv.b,
kjv.id,
kjv.t,
kjv.v,
ke.n,
ke.author
FROM t_kjv kjv
LEFT JOIN key_english ke on kjv.b = ke.b
WHERE blah = %s''' % blah
df_verses = pd.read_sql(verses_sql, con, index_col='id')
Выполнение этого способа означает, что вы также можете передать dict в многострочную строку, если вы предпочитаете, чтобы:
>>> d = { 'vars': "variables", 'example': "example" }
>>> s = "This is an {example} with {vars}"
>>> s.format(**d)
'This is an example with variables'