Введение в взаимодействие с базами данных
В современной разработке программного обеспечения работа с данными является одной из ключевых задач. Для хранения и управления данными используются системы управления базами данных (СУБД), которые можно разделить на два основных типа: SQL (реляционные) и NoSQL (нереляционные).
Для взаимодействия с базами данных в Python используются различные библиотеки. SQLAlchemy — это мощный ORM (Object-Relational Mapping) и инструментарий SQL, который поддерживает множество СУБД. Psycopg2 — это популярный адаптер PostgreSQL для Python, предоставляющий прямой доступ к базе данных.
SQL vs NoSQL: Сравнение подходов
Реляционные (SQL) и нереляционные (NoSQL) базы данных имеют различные архитектуры, модели данных и варианты использования.
SQL базы данных
Реляционные базы данных организуют данные в таблицы со строгой структурой. Они используют язык SQL (Structured Query Language) для выполнения запросов и управления данными.
Примеры: PostgreSQL, MySQL, SQLite, Oracle
Преимущества:
- Строгая схема данных и целостность
- Сложные запросы с JOIN операциями
- Транзакции ACID (атомарность, согласованность, изолированность, долговечность)
NoSQL базы данных
Нереляционные базы данных используют различные модели хранения данных: документные, ключ-значение, колоночные, графовые.
Примеры: MongoDB (документная), Redis (ключ-значение), Cassandra (колоночная), Neo4j (графовая)
Преимущества:
- Гибкая схема данных
- Горизонтальная масштабируемость
- Высокая производительность для определенных сценариев
| Критерий | SQL | NoSQL |
|---|---|---|
| Модель данных | Реляционная (таблицы) | Разнообразная (документы, ключ-значение и т.д.) |
| Схема данных | Строгая, предопределенная | Гибкая, динамическая |
| Масштабируемость | Вертикальная | Горизонтальная |
| Язык запросов | SQL | Зависит от СУБД |
| Транзакции | ACID | BASE (Basically Available, Soft state, Eventually consistent) |
SQLAlchemy: Универсальный инструмент для работы с базами данных
SQLAlchemy — это популярный Python SQL toolkit и Object Relational Mapper, который предоставляет разработчикам полную мощь и гибкость SQL. Он поддерживает множество СУБД, включая PostgreSQL, MySQL, SQLite, Oracle и другие.
Основные возможности SQLAlchemy
- Поддержка ORM для работы с базой данных как с объектами Python
- Генерация SQL выражений через Core компонент
- Поддержка транзакций и сессий
- Миграции схемы базы данных через Alembic
- Поддержка пула соединений
- Интеграция с асинхронным кодом через asyncio
Пример использования SQLAlchemy ORM
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
# Определение модели
Base = declarative_base()
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String(50))
email = Column(String(100), unique=True)
def __repr__(self):
return f"<User(name='{self.name}', email='{self.email}')>"
# Создание подключения
engine = create_engine('postgresql://user:password@localhost/mydatabase')
# Создание таблиц
Base.metadata.create_all(engine)
# Создание сессии
Session = sessionmaker(bind=engine)
session = Session()
# Добавление данных
new_user = User(name='Иван Иванов', email='ivan@example.com')
session.add(new_user)
session.commit()
# Запрос данных
users = session.query(User).filter_by(name='Иван Иванов').all()
print(users)
Psycopg2: Адаптер PostgreSQL для Python
Psycopg2 — это наиболее популярный адаптер базы данных PostgreSQL для языка Python. Он реализует спецификацию DB-API 2.0 и предоставляет прямой, эффективный доступ к PostgreSQL.
Основные возможности Psycopg2
- Полная поддержка PostgreSQL
- Поддержка транзакций и изоляции
- Асинхронные запросы
- Уведомления и копирование данных
- Поддержка больших объектов
- Интеграция с контекстными менеджерами Python
Пример использования Psycopg2
import psycopg2
from psycopg2 import sql
# Установка подключения к базе данных
conn = psycopg2.connect(
dbname="mydatabase",
user="user",
password="password",
host="localhost",
port="5432"
)
# Создание курсора
cur = conn.cursor()
# Создание таблицы
cur.execute("""
CREATE TABLE IF NOT EXISTS employees (
id SERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL,
position VARCHAR(100),
salary DECIMAL(10, 2)
)
""")
# Вставка данных
cur.execute(
"INSERT INTO employees (name, position, salary) VALUES (%s, %s, %s)",
("Алексей Петров", "Разработчик", 85000.00)
)
# Параметризованный запрос с использованием sql.SQL
query = sql.SQL("INSERT INTO employees (name, position, salary) VALUES ({}, {}, {})").format(
sql.Literal("Мария Сидорова"),
sql.Literal("Аналитик данных"),
sql.Literal(75000.00)
)
cur.execute(query)
# Выборка данных
cur.execute("SELECT * FROM employees WHERE salary > %s", (70000.00,))
rows = cur.fetchall()
for row in rows:
print(f"ID: {row[0]}, Имя: {row[1]}, Должность: {row[2]}, Зарплата: {row[3]}")
# Фиксация изменений и закрытие соединения
conn.commit()
cur.close()
conn.close()
Практические примеры
Работа с SQLAlchemy и несколькими СУБД
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
# Подключение к разным СУБД
engines = {
'postgresql': create_engine('postgresql://user:pass@localhost/dbname'),
'mysql': create_engine('mysql+pymysql://user:pass@localhost/dbname'),
'sqlite': create_engine('sqlite:///example.db')
}
# Создание таблицы с помощью Core (без ORM)
metadata = MetaData()
users = Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(50)),
Column('email', String(100))
)
# Создание таблицы во всех базах данных
for db_type, engine in engines.items():
print(f"Создание таблицы в {db_type}...")
metadata.create_all(engine)
print(f"Готово!")
Использование транзакций в Psycopg2
import psycopg2
from psycopg2 import Error
try:
conn = psycopg2.connect(
dbname="mydatabase",
user="user",
password="password",
host="localhost"
)
conn.autocommit = False # Отключение автоматической фиксации
cur = conn.cursor()
# Начало транзакции
cur.execute("BEGIN")
# Несколько операций в одной транзакции
cur.execute("UPDATE accounts SET balance = balance - 100 WHERE id = 1")
cur.execute("UPDATE accounts SET balance = balance + 100 WHERE id = 2")
# Фиксация транзакции
conn.commit()
print("Транзакция успешно завершена")
except (Exception, Error) as error:
print(f"Ошибка при выполнении транзакции: {error}")
if conn:
conn.rollback() # Откат транзакции при ошибке
print("Транзакция откачена")
finally:
if conn:
cur.close()
conn.close()