Подключение к базе данных с помощью SQLAlchemy
Создавайте движок SQLAlchemy для SQLite и PostgreSQL и передавайте его в pd.read_sql, чтобы загрузить таблицу в DataFrame.
«Подключение к базе данных с помощью SQLAlchemy» — бесплатный урок Pandas & NumPy Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Pandas & NumPy Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Pandas & NumPy Academy содержит 4 уроков всего.
Зачем подключать Pandas к базам данных
Большая часть производственных данных хранится в реляционных базах данных — PostgreSQL, MySQL, SQLite или SQL Server, — а не в CSV-файлах. Прямое подключение Pandas к базе данных позволяет загрузить данные в DataFrame с помощью запроса, отправить очищенные DataFrame обратно в таблицы и объединить аналитические возможности Python с возможностями базы данных по индексированию и объединению. Связующим звеном между Pandas и базами данных служит SQLAlchemy — стандартная библиотека Python для абстракции работы с базами данных.
Установка SQLAlchemy
SQLAlchemy — это набор инструментов SQL и ORM для Python. Для интеграции с Pandas нужен только слой Core, а не ORM. Установите его командой pip install sqlalchemy. Также потребуется драйвер конкретной базы данных: psycopg2 для PostgreSQL, pymysql для MySQL или sqlite3 (встроен в Python) для SQLite. SQLAlchemy выступает в роли уровня абстракции: один и тот же код Pandas работает с любой поддерживаемой базой данных, если изменить только строку подключения.
# Install dependencies
# pip install sqlalchemy psycopg2-binary # for PostgreSQL
# pip install sqlalchemy pymysql # for MySQL
# sqlite3 is built into Python
import sqlalchemy as sa
import pandas as pd
print('SQLAlchemy version:', sa.__version__)Создание движка подключения
Первый шаг — создать движок SQLAlchemy с помощью URL-адреса подключения, в котором указаны тип базы данных, учётные данные, узел, порт и имя базы данных. Движок служит фабрикой подключений к базе данных — он не открывает подключение, пока оно действительно не понадобится. Передайте этот движок функциям Pandas pd.read_sql() и df.to_sql(). Никогда не указывайте учётные данные непосредственно в коде: считывайте их из переменных среды или менеджера секретов.
import sqlalchemy as sa
import os
# SQLite (file-based, no server needed)
sqlite_engine = sa.create_engine('sqlite:///mydata.db')
# PostgreSQL
# pg_url = 'postgresql://user:pass@localhost:5432/mydb'
# pg_engine = sa.create_engine(pg_url)
# From environment variable (safer)
# pg_engine = sa.create_engine(os.environ['DATABASE_URL'])
print(sqlite_engine)
print(type(sqlite_engine))Чтение таблицы с помощью pd.read_sql_table()
pd.read_sql_table('table_name', con=engine) считывает всю таблицу базы данных в DataFrame. Функция автоматически определяет типы данных столбцов по схеме базы данных: целые числа остаются целыми числами, временные метки — датами и временем и т. д. Это точнее, чем определение типов при чтении CSV. Вы также можете ограничить набор столбцов с помощью аргумента columns и отфильтровать строки с помощью schema для схем баз данных, отличных от используемой по умолчанию. Будьте осторожны с очень большими таблицами: все данные загружаются в RAM.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Read a full table
df = pd.read_sql_table('orders', con=engine)
print(df.shape)
print(df.dtypes)
print(df.head())Выполнение запросов с помощью pd.read_sql_query()
pd.read_sql_query('SELECT ...', con=engine) выполняет произвольную инструкцию SQL SELECT и возвращает результаты в виде DataFrame. Это наиболее гибкий подход: можно фильтровать, объединять и агрегировать данные в SQL ещё до их загрузки в Pandas, загружая только нужные строки и столбцы. Записывайте запрос как обычную строку Python. Никогда не вставляйте пользовательский ввод в запросы конкатенацией — используйте параметризованные запросы для предотвращения SQL-инъекций.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
query = '''
SELECT customer_id, SUM(amount) AS total_spent,
COUNT(*) AS num_orders
FROM orders
WHERE status = 'completed'
GROUP BY customer_id
ORDER BY total_spent DESC
LIMIT 100
'''
top_customers = pd.read_sql_query(query, con=engine)
print(top_customers.head())Параметризованные запросы для безопасности
Никогда не создавайте SQL-запросы конкатенацией строк со значениями, предоставленными пользователем, — это создаёт уязвимости для SQL-инъекций. Вместо этого используйте параметризованные запросы: передавайте параметры в виде словаря с именованными заполнителями. SQLAlchemy обрабатывает экранирование. Для заполнителей в текстовых запросах SQLAlchemy используется синтаксис :name, а для запросов в стиле psycopg2 — %(name)s. Всегда используйте параметризацию, даже во внутренних скриптах, чтобы сформировать полезную привычку.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Safe: parameterised query
params = {'status': 'completed', 'min_amount': 500.0}
query = sa.text(
'SELECT * FROM orders WHERE status = :status AND amount > :min_amount'
)
with engine.connect() as conn:
df = pd.read_sql_query(query, con=conn, params=params)
print(f'Loaded {len(df)} rows')Обработка больших результатов запросов частями
Для больших результатов запросов используйте chunksize в pd.read_sql_query(), чтобы получать итератор DataFrames, а не загружать всё сразу. Это аналогично поведению pd.read_csv(chunksize=...), но строки извлекаются из базы данных пакетами. Сочетайте этот подход с шаблоном накопления промежуточного результата, чтобы агрегировать результаты запросов с миллионами строк и не исчерпать RAM.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('postgresql://user:pass@host/db')
total = 0.0
count = 0
for chunk in pd.read_sql_query(
'SELECT amount FROM orders',
con=engine,
chunksize=50000
):
total += chunk['amount'].sum()
count += len(chunk)
print(f'Mean amount: {total/count:.2f}')Контекстные менеджеры подключений
Всегда открывайте подключения к базе данных внутри контекстного менеджера (with engine.connect() as conn:), чтобы подключение корректно закрывалось даже при возникновении исключения. Если не закрывать подключения, в рабочей среде это приводит к исчерпанию пула подключений, из-за чего новые запросы зависают в ожидании свободного места. Пул подключений SQLAlchemy управляет фиксированным числом подключений и автоматически повторно использует их при работе с контекстными менеджерами.
import pandas as pd
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
# Using context manager — connection always closed properly
with engine.connect() as conn:
df = pd.read_sql_query(
'SELECT * FROM products WHERE category = "Electronics"',
con=conn
)
print(f'Products loaded: {len(df)}')
# Connection is automatically returned to the pool hereПроверка схемы базы данных
Прежде чем писать запросы, нужно знать, какие таблицы и столбцы существуют. Инспектор SQLAlchemy позволяет получить схему базы данных без написания обычного SQL. inspector.get_table_names() выводит список всех таблиц, а inspector.get_columns('table') возвращает имена и типы столбцов. Это полезно при работе с незнакомыми базами данных и аккуратнее, чем ручной запуск PRAGMA table_info() или \d tablename.
import sqlalchemy as sa
engine = sa.create_engine('sqlite:///sales.db')
inspector = sa.inspect(engine)
# List all tables
tables = inspector.get_table_names()
print('Tables:', tables)
# Get columns for the 'orders' table
for col in inspector.get_columns('orders'):
print(f' {col["name"]}: {col["type"]}')Закрытие движков и рекомендации
В долгоживущих скриптах или веб-приложениях вызывайте engine.dispose() после завершения работы, чтобы закрыть все подключения в пуле. Для коротких скриптов очисткой занимается сборщик мусора Python. Рекомендации по работе с подключениями к базам данных в конвейерах обработки данных: создавайте движок один раз в начале скрипта и повторно используйте его, применяйте стандартные настройки пула подключений (pool_size=5), включайте pool_pre_ping=True, чтобы автоматически подключаться заново, если сервер базы данных перезапустился между запросами.
import sqlalchemy as sa
# Production-grade engine creation
engine = sa.create_engine(
'postgresql://user:pass@host:5432/mydb',
pool_size=5, # max 5 persistent connections
max_overflow=10, # allow 10 temporary extra connections
pool_pre_ping=True, # verify connection before use
connect_args={'connect_timeout': 10}
)
# ... run all your queries ...
# At the end of the application/script
engine.dispose()
print('Engine disposed')Сравнение скорости read_sql и read_csv
Если данные уже находятся в базе данных с подходящими индексами, pd.read_sql_query с отфильтрованным запросом часто оказывается быстрее, чем экспорт в CSV с последующим чтением. Сервер базы данных применяет фильтры до отправки данных, уменьшая объём сетевой передачи и затрат на разбор. Для очень широких таблиц база данных также может выбрать только нужные столбцы. Однако чтение из удалённой базы данных через медленную сеть может быть медленнее чтения локального файла Parquet — всегда измеряйте производительность обоих вариантов в своей конкретной конфигурации.
import pandas as pd
import sqlalchemy as sa
import time
engine = sa.create_engine('sqlite:///data.db')
# Database read with server-side filter
start = time.time()
df_sql = pd.read_sql_query(
'SELECT * FROM transactions WHERE amount > 100 AND year = 2024',
con=engine
)
print(f'SQL read: {time.time()-start:.3f}s, {len(df_sql):,} rows')Быстрая проверка
Проверьте, насколько хорошо вы поняли концепции анализа данных из этого урока.
Итоги урока
В этом уроке вы узнали, что sa.create_engine() создаёт повторно используемую фабрику подключений из строки URL, pd.read_sql_query() выполняет произвольный SQL и возвращает DataFrame, а параметризованные запросы с помощью sa.text() и params предотвращают уязвимости для SQL-инъекций. Далее мы рассмотрим выполнение более сложных SQL-запросов из Pandas и объединение SQL с логикой Python.
Часто задаваемые вопросы
Урок «Подключение к базе данных с помощью SQLAlchemy» бесплатный?
Да — полный текст урока «Подключение к базе данных с помощью SQLAlchemy» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Pandas & NumPy Academy, подпишись на CoddyKit PRO. Курс Pandas & NumPy Academy содержит 4 уроков всего.
Чему я научусь в уроке «Подключение к базе данных с помощью SQLAlchemy»?
Создавайте движок SQLAlchemy для SQLite и PostgreSQL и передавайте его в pd.read_sql, чтобы загрузить таблицу в DataFrame. Ты практикуешь Pandas & NumPy Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Pandas & NumPy Academy?
Предыдущий опыт не требуется. Pandas & NumPy Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Подключение к базе данных с помощью SQLAlchemy»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Pandas & NumPy Academy?
Да. Каждый урок Pandas & NumPy Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Подключение к базе данных с помощью SQLAlchemy
- Выполнение SQL-запросов из Pandas
- Запись DataFrames в таблицы базы данных
- Pandas или SQL: выбор подходящего инструмента