import pandas df = pandas.read_sql(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, columns=None, chunksize=None, dtype_backend=no_default, dtype=None)
sql
- SQL-запрос, который необходимо выполнить или имя таблицы.
con
- строка соединения с базой данных в стиле SQLAlchemy
или объект соединения (SQLAlchemy
, sqlite3
, DBAPI2
или ADBC
). Использование SQLAlchemy
позволяет использовать любую БД, поддерживаемую этой библиотекой. Объект DBAPI2
поддерживается только sqlite3
.
Пользователь несет ответственность за закрытие объекта соединения
ADBC
иSQLAlchemy
. Соединение, переданное как строка в стилеSQLAlchemy
закрывается автоматически.
index_col=None
- строка с именем столбца для установки в качестве индекса или список имен для MultiIndex
.
coerce_float=True
- пытается преобразовать значения таких объектов как например, decimal.Decimal
в числа float
.
params=None
- список параметров, которые нужно передать в ожидаемый интерфейс форматирования SQL-запроса к базе данных. Синтаксис, используемый для передачи параметров, зависит от драйвера базы данных. Например, модуль psycopg2
использует форматирование %(name)s
, следовательно необходимо использовать params={’name’ : ‘value’}
.
Напомним стили форматирования из PEP249:
qmark
: ...WHERE name=?
;numeric
: ...WHERE name=:1
;named
: ...WHERE name=:name
;format
: ...WHERE name=%s
;pyformat
: ...WHERE name=%(name)s
.parse_dates=None
- принимает:
{column_name: format}
, где format
совместима с правилами форматирования strftime
в случае анализа времени строки или является одним из ('D'
, 's'
, 'ns'
, 'ms'
, 'us'
) в случае анализа целочисленных временных меток.{column_name: kwargs}
, где kwargs
соответствует ключевым аргументам функции pandas.to_datetime()
. Особенно полезно для баз данных без встроенной поддержки datetime
, таких как SQLite3
.columns=None
- список имен столбцов для выбора из таблицы SQL (используется только при чтении таблицы).
chunksize=None
- если указано, то возвращает итератор, где chunksize
- количество строк, включаемых в каждый фрагмент.
dtype_backend=no_default
- (экспериментальный) внутренний тип данных, применяемый к результирующему DataFrame
.
Поведение выглядит следующим образом:
'numpy_nullable'
: возвращает фрейм с поддержкой null-dtype
(по умолчанию).'pyarrow'
: возвращает фрейм данных ArrowDtype
с нулевым значением, поддерживаемый pyarrow
.dtype=None
- желаемый тип данных для столбцов результирующего DataFrame
. Например, np.float64
(пытается применить ко всем столбцам) или словарь {’a’: np.float64, ‘b’: np.int32, ‘c’: ‘Int64’}
, где ключ является именем столбца. Аргумент игнорируется, если вместо запроса передается таблица.
pandas.read_sql()
:Функция read_sql()
модуля pandas
считывает SQL-запрос или таблицу базы данных в DataFrame
.
Функция pandas.read_sql()
является удобной оберткой двух функций pandas.read_sql_table()
и pandas.read_sql_query()
(для обратной совместимости). Она будет делегировать конкретную функцию в зависимости от предоставленных входных данных. SQL-запрос будет направлен в pandas.read_sql_query()
, а имя таблицы базы данных - в pandas.read_sql_table()
. Обратите внимание, что делегированная функция может иметь более конкретную функциональность.
Чтобы подключиться с помощью драйвера ADBC
, необходимо установить adbc_driver_sqlite
с помощью менеджера пакетов. После установки можно использовать интерфейс DBAPI, предоставляемый драйвером ADBC.
import adbc_driver_sqlite.dbapi as sqlite_dbapi # Создаем соединение with sqlite_dbapi.connect("sqlite:///:memory:") as conn: df = pd.read_sql("data", conn)
Чтобы подключиться к SQLAlchemy
, используем функцию create_engine()
для создания объекта механизма из URI базы данных. Нужно создать движок только один раз для каждой базы данных, к которой подключаемся.
from sqlalchemy import create_engine # Создаем движок. engine = create_engine("sqlite:///:memory:")
Если нужно управлять своими собственными подключениями, то можно передать одно из них. В приведенном ниже примере открывается соединение с базой данных с помощью контекстного менеджера Python, который автоматически закрывает соединение после завершения блока.
# создадим экспериментальную базу данных >>> import datetime >>> c = ["id", "Date", "Col_1", "Col_2", "Col_3"] d = [ (26, datetime.datetime(2010, 10, 18), "X", 27.5, True), (42, datetime.datetime(2010, 10, 19), "Y", -12.5, False), (63, datetime.datetime(2010, 10, 20), "Z", 5.73, True), ] >>> import pandas as pd >>> data = pd.DataFrame(d, columns=c) >>> from sqlalchemy import create_engine >>> engine = create_engine("sqlite:///database.db") with engine.connect() as conn, conn.begin(): # если возникают ошибки, то обновите `SQLAlchemy` # например, pip install -U SQLAlchemy data.to_sql("data", con=conn) # теперь прочитаем ее with engine.connect() as conn, conn.begin(): data = pd.read_sql("data", conn) >>> data # index id Date Col_1 Col_2 Col_3 # 0 0 26 2010-10-18 X 27.50 True # 1 1 42 2010-10-19 Y -12.50 False # 2 2 63 2010-10-20 Z 5.73 True
from sqlalchemy import create_engine engine = create_engine("postgresql://scott:tiger@localhost:5432/mydatabase") engine = create_engine("mysql+mysqldb://scott:tiger@localhost/foo") engine = create_engine("oracle://scott:tiger@127.0.0.1:1521/sidname") engine = create_engine("mssql+pyodbc://mydsn") # sqlite://<nohostname>/<path> # где <path> относительный: engine = create_engine("sqlite:///foo.db") # или абсолютный, начиная с косой черты: engine = create_engine("sqlite:////absolute/path/to/foo.db")
Можно использовать конструкции SQLAlchemy
для описания запроса. Используем sqlalchemy.text()
для указания параметров запроса нейтральным способом для серверной части.
import sqlalchemy as sa pd.read_sql( sa.text("SELECT * FROM data where Col_1=:col1"), engine, params={"col1": "X"} )
Если есть описание базы данных SQLAlchemy
, то можно выразить запрос, используя выражения SQLAlchemy
.
metadata = sa.MetaData() data_table = sa.Table( "data", metadata, sa.Column("index", sa.Integer), sa.Column("Date", sa.DateTime), sa.Column("Col_1", sa.String), sa.Column("Col_2", sa.Float), sa.Column("Col_3", sa.Boolean), ) pd.read_sql(sa.select(data_table).where(data_table.c.Col_3 is True), engine)
Можно комбинировать выражения SQLAlchemy
с аргументами, передаваемыми в pandas.read_sql()
, используя sqlalchemy.bindparam()
.
import datetime as dt expr = sa.select(data_table).where(data_table.c.Date > sa.bindparam("date")) pd.read_sql(expr, engine, params={"date": dt.datetime(2010, 10, 18)})
pandas.read_sql()
:При использовании базы данных SQLite принимаются только ванильные запросы SQL, поэтому указание только имени таблицы SQL (без SQL-запроса) приведет к ошибке.
>>> import pandas as pd >>> from sqlite3 import connect >>> conn = connect(':memory:') # создадим `DataFrame` >>> df = pd.DataFrame(data=[[0, '10/11/12'], [1, '12/11/10']], columns=['int_column', 'date_column']) # запишем `DataFrame` в SQLite >>> df.to_sql(name='test_data', con=conn) # 2
Читаем:
>>> pd.read_sql('SELECT int_column, date_column FROM test_data', conn) # int_column date_column # 0 0 10/11/12 # 1 1 12/11/10
или если данные хранились в БД PostgreSQL
:
>>> pd.read_sql('test_data', 'postgres:///db_name')
Анализируем даты в столбцах с помощью аргумента parse_dates
. Аргумент parse_dates
вызывает функцию pandas.to_datetime()
для предоставленных столбцов. Пользовательские значения аргументов для применения to_datetime()
к столбцу указываются при помощи спецификации словаря:
>>> pd.read_sql('SELECT int_column, date_column FROM test_data', conn, ... parse_dates={"date_column": {"format": "%d/%m/%y"}}) # int_column date_column # 0 0 2012-11-10 # 1 1 2010-11-12
С версии pandas
2.2 поддерживает чтение БД через драйверы ADBC
>>> from adbc_driver_postgresql import dbapi >>> with dbapi.connect('postgres:///db_name') as conn: ... pd.read_sql('SELECT int_column FROM test_data', conn) # int_column # 0 0 # 1 1
pandas.read_sql_query(sql, con, index_col=None, coerce_float=True, params=None, parse_dates=None, chunksize=None, dtype=None, dtype_backend=no_default)
:Функция pandas.read_sql_query()
читает SQL-запрос в DataFrame
. Возвращает DataFrame
, соответствующий набору результатов строки запроса.
Чтобы использовать один из столбцов в качестве индекса, необходимо указать аргумент index_col
, в противном случае будет использоваться индекс по умолчанию RangeIndex
.
Аргумент sql
представляет собой строку SQL-запроса, который необходимо выполнить. Можно передать строку запроса в стиле SQLAlchemy
.
Аргумент con
представляет собой строку соединения с базой данных в стиле SQLAlchemy
или объект соединения (SQLAlchemy
или sqlite3
). Использование SQLAlchemy
позволяет использовать любую БД, поддерживаемую этой библиотекой. Пользователь несет ответственность за закрытие соединения для соединения ADBC
и возможности подключения SQLAlchemy
. Соединение, переданное как строка в стиле SQLAlchemy
закрывается автоматически.
Описание остальных аргументов совпадают с описанием аналогичных аргументов, принимаемых функцией pandas.read_sql()
pandas.read_sql_query()
:Любые значения даты и времени с информацией о часовом поясе, анализируемые с помощью аргумента parse_dates
, будут преобразованы в формат UTC.
>>> import pandas as pd >>> from sqlalchemy import create_engine # БД `database.db` была создана выше >>> engine = create_engine("sqlite:///database.db") >>> with engine.connect() as conn, conn.begin(): ... data = pd.read_sql_query("SELECT * FROM data", conn)
Конечно, можно указать и более "сложный" запрос.
>>> with engine.connect() as conn, conn.begin(): ... data = pd.read_sql_query("SELECT id, Col_1, Col_2 FROM data WHERE id = 42;", conn)
Функция read_sql_query()
поддерживает аргумент chunksize
. Если указать, то будет возвращаться итератор по фрагментам результата запроса:
>>> import pandas as pd >>> import numpy as np >>> df = pd.DataFrame(np.random.randn(20, 3), columns=list("abc")) >>> df.to_sql(name="data_chunks", con=engine, index=False) for chunk in pd.read_sql_query("SELECT * FROM data_chunks", engine, chunksize=5): print(chunk) # a b c # 0 -0.395347 -0.822726 -0.363777 # 1 1.676124 -0.908102 -1.391346 # 2 -1.094269 0.278380 1.205899 # 3 1.503443 0.932171 -0.709459 # 4 -0.645944 -1.351389 0.132023 # a b c # 0 0.210427 0.192202 0.661949 # 1 1.690629 -1.046044 0.618697 # 2 -0.013863 1.314289 1.951611 # 3 -1.485026 0.304662 1.194757 # 4 -0.446717 0.528496 -0.657575 # a b c # 0 -0.876654 0.336252 0.172668 # 1 0.337684 -0.411202 -0.828394 # 2 -0.244413 1.094948 0.087183 # 3 1.125934 -1.480095 1.205944 # 4 -0.451849 0.452214 -2.208192 # a b c # 0 -2.061019 0.044184 -0.017118 # 1 1.248959 -0.675595 -1.908296 # 2 -0.125934 1.491974 0.648726 # 3 0.391214 0.438609 1.634248 # 4 1.208707 -1.535740 1.620399
pandas.read_sql_table(table_name, con, schema=None, index_col=None, coerce_float=True, parse_dates=None, columns=None, chunksize=None, dtype_backend=no_default)
:Функция pandas.read_sql_table()
учитывая имя таблицы (аргумент table_name
) и возможность подключения SQLAlchemy
(аргумент con
), читает SQL-таблицe в DataFrame
. Эта функция не поддерживает соединения DBAPI
.
Аргумент table_name
- это строка с именем таблицы в базе данных.
Аргумент con
может быть строкой подключения к БД (URI) в стиле SQLAlchemy
или объект подключения SQLAlchemy
Аргумент schema
представляет собой строку с именем схемы SQL в базе данных для запроса (если это поддерживается БД). Если None
, то использует схему по умолчанию.
Описание остальных аргументов совпадают с описанием аналогичных аргументов, принимаемых функцией pandas.read_sql()
pandas.read_sql_table()
:>>> from sqlalchemy import create_engine # БД `database.db` была создана выше >>> engine = create_engine("sqlite:///database.db") >>> pd.read_sql_table("data", engine) # index id Date Col_1 Col_2 Col_3 # 0 0 26 2010-10-18 X 27.50 True # 1 1 42 2010-10-19 Y -12.50 False # 2 2 63 2010-10-20 Z 5.73 True
Имя столбца в качестве индекса DataFrame
и указать подмножество столбцов для чтения.
>>> pd.read_sql_table("data", engine, index_col="id") index Date Col_1 Col_2 Col_3 id 26 0 2010-10-18 X 27.50 True 42 1 2010-10-19 Y -12.50 False 63 2 2010-10-20 Z 5.73 True >>> pd.read_sql_table("data", engine, columns=["Col_1", "Col_2"]) Col_1 Col_2 0 X 27.50 1 Y -12.50 2 Z 5.73
Заставим явно анализировать столбцы как даты:
>>> pd.read_sql_table("data", engine, parse_dates=["Date"]) index id Date Col_1 Col_2 Col_3 0 0 26 2010-10-18 X 27.50 True 1 1 42 2010-10-19 Y -12.50 False 2 2 63 2010-10-20 Z 5.73 True
При необходимости можно явно указать строку формата или набор аргументов для передачи в pandas.to_datetime()
:
>>> pd.read_sql_table("data", engine, parse_dates={"Date": "%Y-%m-%d"}) index id Date Col_1 Col_2 Col_3 0 0 26 2010-10-18 X 27.50 True 1 1 42 2010-10-19 Y -12.50 False 2 2 63 2010-10-20 Z 5.73 True >>> pd.read_sql_table( ... "data", ... engine, ... parse_dates={"Date": {"format": "%Y-%m-%d %H:%M:%S"}}, ... ) index id Date Col_1 Col_2 Col_3 0 0 26 2010-10-18 X 27.50 True 1 1 42 2010-10-19 Y -12.50 False 2 2 63 2010-10-20 Z 5.73 True