Подтвердить что ты не робот

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?

4b9b3361

Ответ 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'