← Назад к вопросам
Делал ли какие-то интеграции с базой данной на Flask
2.0 Middle🔥 191 комментариев
#FastAPI и Flask#REST API и HTTP#Базы данных (SQL)
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Интеграции с базой данных на Flask
Да, я имею значительный опыт работы с интеграциями баз данных в Flask приложениях. Это ключевой компонент практически любого веб-приложения, и я хотел бы поделиться моим опытом и лучшими практиками.
Основные подходы к интеграции БД в Flask
SQLAlchemy ORM Это наиболее популярный и рекомендуемый подход. Flask-SQLAlchemy расширение предоставляет удобный интерфейс для работы с различными РСУБД (PostgreSQL, MySQL, SQLite).
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@localhost/mydb'
db = SQLAlchemy(app)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), unique=True, nullable=False, index=True)
username = db.Column(db.String(80), nullable=False)
password_hash = db.Column(db.String(255), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
posts = db.relationship('Post', backref='author', lazy='select', cascade='all, delete-orphan')
def __repr__(self):
return f'<User {self.username}>'
class Post(db.Model):
__tablename__ = 'posts'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False)
created_at = db.Column(db.DateTime, default=datetime.utcnow)
# Создание таблиц
with app.app_context():
db.create_all()
Операции CRUD
Create (Создание)
@app.route('/users', methods=['POST'])
def create_user():
data = request.get_json()
user = User(
email=data['email'],
username=data['username'],
password_hash=hash_password(data['password'])
)
db.session.add(user)
db.session.commit()
return jsonify({'id': user.id, 'email': user.email}), 201
Read (Чтение)
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
user = User.query.get_or_404(user_id)
return jsonify({
'id': user.id,
'email': user.email,
'username': user.username,
'created_at': user.created_at.isoformat()
})
@app.route('/users', methods=['GET'])
def list_users():
page = request.args.get('page', 1, type=int)
per_page = 20
paginated = User.query.paginate(page=page, per_page=per_page)
return jsonify({
'items': [{'id': u.id, 'email': u.email} for u in paginated.items],
'total': paginated.total,
'pages': paginated.pages
})
Update (Обновление)
@app.route('/users/<int:user_id>', methods=['PUT'])
def update_user(user_id):
user = User.query.get_or_404(user_id)
data = request.get_json()
if 'email' in data:
user.email = data['email']
if 'username' in data:
user.username = data['username']
db.session.commit()
return jsonify({'message': 'User updated'})
Delete (Удаление)
@app.route('/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
user = User.query.get_or_404(user_id)
db.session.delete(user)
db.session.commit()
return jsonify({'message': 'User deleted'}), 204
Сложные запросы
Фильтрация и сортировка
@app.route('/posts', methods=['GET'])
def list_posts():
author_id = request.args.get('author_id', type=int)
sort_by = request.args.get('sort', 'created_at')
query = Post.query
if author_id:
query = query.filter_by(user_id=author_id)
posts = query.order_by(sort_by).all()
return jsonify([
{'id': p.id, 'title': p.title, 'author': p.author.username}
for p in posts
])
Join запросы
@app.route('/users-with-posts', methods=['GET'])
def users_with_posts():
results = db.session.query(User, db.func.count(Post.id)).join(Post).group_by(User.id).all()
return jsonify([
{'user': u.username, 'post_count': count}
for u, count in results
])
Транзакции и обработка ошибок
@app.route('/transfer', methods=['POST'])
def transfer_funds():
try:
from_user_id = request.json['from']
to_user_id = request.json['to']
amount = request.json['amount']
from_user = User.query.get_or_404(from_user_id)
to_user = User.query.get_or_404(to_user_id)
if from_user.balance < amount:
return jsonify({'error': 'Insufficient funds'}), 400
from_user.balance -= amount
to_user.balance += amount
db.session.commit()
return jsonify({'message': 'Transfer successful'}), 200
except Exception as e:
db.session.rollback()
return jsonify({'error': str(e)}), 500
Миграции БД с Alembic
# Инициализация
# flask db init
# flask db migrate -m "Initial migration"
# flask db upgrade
from flask_migrate import Migrate
migrate = Migrate(app, db)
Оптимизация производительности
Использование индексов
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(120), unique=True, index=True)
username = db.Column(db.String(80), index=True)
Eager loading для избежания N+1 проблемы
posts = Post.query.options(db.joinedload(Post.author)).all()
Кэширование результатов
from flask_caching import Cache
cache = Cache(app, config={'CACHE_TYPE': 'simple'})
@app.route('/users/<int:user_id>')
@cache.cached(timeout=300)
def get_user(user_id):
return db.session.query(User).get(user_id)
Заключение
В моем опыте я работал с:
- PostgreSQL и MySQL интеграциями на Flask
- Сложными отношениями между сущностями (many-to-many, полиморфные связи)
- Миграциями БД и версионированием схемы
- Оптимизацией запросов и предотвращением N+1 проблемы
- Обработкой транзакций и откатом при ошибках
Это делает меня уверенным разработчиком при работе с персистентностью данных в Flask приложениях.