Урок 88. Презентация проекта

📁 Блок: Финальный проект ⏱️ Время изучения: ~180 мин 🎯 Сложность: Продвинутая
#from #as #and #min #max #count #import #def #return #with #close #try #finally #list

⚡ Кратко: справочник

Ключевые запросы и методы для финального проекта: SQL к sakila через PyMySQL и запись/чтение логов через PyMongo.

  • Поиск по названию: WHERE title LIKE %s LIMIT 10 OFFSET %s.
  • Поиск по жанру и годам: JOIN category и film_category с фильтрами WHERE.
  • Список жанров и диапазон годов — отдельные служебные запросы.
  • Логи в MongoDB: insert_one, статистика — aggregate с $group или sort + limit.

Что запомнить: всегда используйте параметризованные запросы и закрывайте соединения.

Частая ошибка: забывать LIMIT/OFFSET или путать порядок аргументов в параметризованном запросе.

🔍 SQL-запросы для базы sakila

Поиск фильмов по ключевому слову в названии

SELECT film_id, title, release_year, description
FROM film
WHERE title LIKE %s
ORDER BY title
LIMIT %s OFFSET %s;

Параметры: ("%matrix%", 10, 0) — ищет «matrix» в названии, возвращает первые 10 результатов.

Поиск фильмов по жанру и диапазону годов

SELECT f.film_id, f.title, c.name AS genre, f.release_year
FROM film f
JOIN film_category fc ON f.film_id = fc.film_id
JOIN category c ON fc.category_id = c.category_id
WHERE c.name = %s
  AND f.release_year BETWEEN %s AND %s
ORDER BY f.release_year, f.title
LIMIT %s OFFSET %s;

Параметры: ("Comedy", 2005, 2012, 10, 0).

Список всех жанров

SELECT name FROM category ORDER BY name;

Минимальный и максимальный год выпуска

SELECT MIN(release_year) AS min_year, MAX(release_year) AS max_year
FROM film;

Количество результатов для пагинации

SELECT COUNT(*) AS total
FROM film
WHERE title LIKE %s;

🐍 PyMySQL: подключение и выполнение запросов

import pymysql
from pymysql.cursors import DictCursor

def get_mysql_connection():
    return pymysql.connect(
        host="mysql.itcareerhub.de",
        user="ich_editor",
        password="verystrongpassword",
        database="sakila",
        cursorclass=DictCursor,
    )

def search_by_keyword(keyword, limit=10, offset=0):
    query = """
        SELECT film_id, title, release_year, description
        FROM film
        WHERE title LIKE %s
        ORDER BY title
        LIMIT %s OFFSET %s
    """
    with get_mysql_connection() as conn:
        with conn.cursor() as cursor:
            cursor.execute(query, (f"%{keyword}%", limit, offset))
            return cursor.fetchall()

🍃 PyMongo: подключение и запись лога

from datetime import datetime
from pymongo import MongoClient

def get_mongo_collection():
    client = MongoClient(
        "mongodb://ich_editor:verystrongpassword"
        "@mongo.itcareerhub.de/?authSource=ich_edit"
    )
    db = client["ich_edit"]
    return client, db["final_project_pd_ivan_ivanov"]

def write_log(search_type, params, results_count):
    client, collection = get_mongo_collection()
    try:
        collection.insert_one({
            "timestamp": datetime.now().isoformat(),
            "search_type": search_type,
            "params": params,
            "results_count": results_count,
        })
    finally:
        client.close()

📊 MongoDB: агрегации для статистики

Топ-5 запросов по частоте

def most_popular(collection, limit=5):
    pipeline = [
        {
            "$group": {
                "_id": {
                    "search_type": "$search_type",
                    "params": "$params"
                },
                "count": {"$sum": 1}
            }
        },
        {"$sort": {"count": -1}},
        {"$limit": limit}
    ]
    return list(collection.aggregate(pipeline))

5 последних уникальных запросов

def latest_unique(collection, limit=5):
    pipeline = [
        {"$sort": {"timestamp": -1}},
        {
            "$group": {
                "_id": {
                    "search_type": "$search_type",
                    "params": "$params"
                },
                "timestamp": {"$first": "$timestamp"}
            }
        },
        {"$sort": {"timestamp": -1}},
        {"$limit": limit}
    ]
    return list(collection.aggregate(pipeline))

📋 Справочная таблица

ЗадачаИнструментКлючевой метод / оператор
Подключиться к MySQLPyMySQLpymysql.connect(...)
Выполнить SELECTPyMySQLcursor.execute(query, params)
Получить все строкиPyMySQLcursor.fetchall()
Параметризованный запросSQLWHERE title LIKE %s
Подключиться к MongoDBPyMongoMongoClient(...)
Записать документPyMongocollection.insert_one(doc)
Прочитать с группировкойPyMongocollection.aggregate(pipeline)
Отсортировать и ограничитьPyMongo{"$sort": ...}, {"$limit": 5}