⚖️ Старый vs Новый: паттерны Flask
Паттерны из лекции (устаревшие) → современные практики Flask 3.x
⚡ Главные отличия
- Лекция:
app = Flask(__name__)напрямую → современно:def create_app() - Лекция:
db = SQLAlchemy(app)→ современно:db.init_app(app) - Лекция:
FLASK_ENV→ современно:FLASK_DEBUGили кастомная переменная
1. Инициализация приложения и БД
Из лекции (старое)
# run.py — всё в одном файле
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import DevelopmentConfig
app = Flask(__name__)
app.config.from_object(DevelopmentConfig)
db = SQLAlchemy(app) # привязка при создании
Проблема: db привязан к одному экземпляру app. При тестировании нельзя создать второе приложение с другой конфигурацией. Нарушает принцип Application Factory.
Современный подход (Flask 3.x)
# app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy() # без привязки к app
def create_app(config_name='development'):
app = Flask(__name__)
from config import config_map
app.config.from_object(config_map[config_name])
db.init_app(app) # привязка при вызове
return app
Преимущество: можно создать несколько экземпляров приложения (например, для тестов), передавая разную конфигурацию.
2. Переменная окружения для конфигурации
Из лекции (старое)
# использование FLASK_ENV
config_name = os.environ.get('FLASK_ENV', 'development')
config_class = {
'development': DevelopmentConfig,
...
}.get(config_name)
app.config.from_object(config_class)
FLASK_ENV устарела в Flask 2.3 и удалена в Flask 3.0. Использование вызывает предупреждение или ошибку.
Современный подход (Flask 3.x)
# Кастомная переменная окружения
import os
config_name = os.environ.get('APP_ENV', 'development')
app = create_app(config_name)
# Отладочный режим — через FLASK_DEBUG
# export FLASK_DEBUG=1 (bash)
# $env:FLASK_DEBUG=1 (PowerShell)
В Flask 3.x FLASK_DEBUG=1 включает дебаг-режим. Для конфигурации используйте свою переменную (APP_ENV или аналог).
3. Маршруты: прямо в run.py vs Blueprints
Из лекции (старое)
# run.py — маршруты смешаны с конфигурацией
from flask import Flask
app = Flask(__name__)
@app.route('/')
def home():
return "Community Pulse"
@app.route('/questions')
def list_questions():
...
@app.route('/questions/add', methods=['POST'])
def add_question():
...
Проблема: при росте проекта run.py разрастается. Нет разделения ответственностей. Сложно поддерживать и тестировать.
Современный подход
# app/routers/questions.py
from flask import Blueprint
questions_bp = Blueprint('questions', __name__)
@questions_bp.route('/')
def list_questions(): ...
@questions_bp.route('/', methods=['POST'])
def add_question(): ...
# app/__init__.py
def create_app():
...
app.register_blueprint(
questions_bp,
url_prefix='/questions'
)
...
Каждый модуль в своём файле. Легко добавлять новые разделы без изменения основного файла.
4. Запросы к БД: legacy Query API vs select()
Flask-SQLAlchemy 2.x / SQLAlchemy 1.x (устаревшее)
# Из лекции — старый Query API
questions = Question.query.all()
question = Question.query.get(question_id)
questions = Question.query.filter_by(
text="..."
).first()
.query — устаревший интерфейс. В SQLAlchemy 2.x помечен как deprecated, в будущих версиях может быть удалён.
SQLAlchemy 2.x (современное)
from sqlalchemy import select
# Все объекты
questions = db.session.scalars(
select(Question)
).all()
# По ID (рекомендованный способ)
question = db.session.get(Question, question_id)
# Фильтрация
from sqlalchemy import select
stmt = select(Question).where(
Question.text.contains("работа")
)
questions = db.session.scalars(stmt).all()
Современный стиль работает одинаково с SQLAlchemy Core и ORM. Рекомендован для всех новых проектов.
5. Структура проекта
Из лекции (упрощённая)
/community_pulse/
|-- run.py # всё: app, config, маршруты, модели
|-- config.py
Подходит только для учебного минимума. Не масштабируется.
Рекомендуемая структура из лекции
/community_pulse/
|-- app/
| |-- __init__.py # create_app(), db
| |-- routers/
| | |-- questions.py # Blueprint questions
| | |-- responses.py # Blueprint responses
| |-- models/
| | |-- questions.py # модель Question
| | |-- responses.py # модель Response
| |-- schemas/
| |-- question.py # Pydantic схемы
| |-- response.py
|-- config.py
|-- run.py
Структура из лекции — уже хорошая модульная организация. Следуйте ей для реального проекта.