/
Sergei777333
/
TechStore
Обзор
Документация
Войти
/
Sergei777333
/
TechStore
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
main
database.py
143 строки
6 KB
Lesnik
Новый коммит
02 авг 2026, 22:28
02 авг 2026, 22:28
a0105d8
Код
Авторство
О чём код?
import asyncio from sqlalchemy import select from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession from db_models import Base, Product as DBProduct, Order, OrderItem from models import Product from datetime import datetime # Асинхронный движок (обязательно aiosqlite для асинхронного SQLite) DATABASE_URL = "sqlite+aiosqlite:///tech_store.db" engine = create_async_engine(DATABASE_URL, echo=False) # Асинхронная фабрика сессий (expire_on_commit=False важен для async) AsyncSessionLocal = async_sessionmaker( bind=engine, class_=AsyncSession, expire_on_commit=False ) async def init_db(): """Создает все таблицы в базе данных""" async with engine.begin() as conn: await conn.run_sync(Base.metadata.create_all) print("✅ База данных инициализирована") async def save_product_to_db(product): """Сохраняет товар в базу данных""" async with AsyncSessionLocal() as db: try: # 1. Проверяем наличие (используем select, а не db.query) stmt = select(DBProduct).where(DBProduct.name == product.name) result = await db.execute(stmt) existing = result.scalar_one_or_none() if existing: print(f"⚠️ Товар '{product.name}' уже существует в БД") return existing # 2. to_dict() это обычный синхронный метод, await ему не нужен! data = product.to_dict() db_product = DBProduct( name=data['name'], price=data['price'], stock=data['stock'], product_type=data.get('product_type', 'Product'), cpu=data.get('cpu'), ram=data.get('ram'), storage=data.get('storage'), screen_size=data.get('screen_size'), camera_mp=data.get('camera_mp'), wireless=data.get('wireless'), noise_cancellation=data.get('noise_cancellation') ) db.add(db_product) await db.commit() # <-- await обязателен await db.refresh(db_product) # <-- await обязателен print(f"✅ Товар '{product.name}' сохранен в БД (id={db_product.id})") return db_product except Exception as e: await db.rollback() # <-- await обязателен print(f"❌ Ошибка при сохранении товара: {e}") raise # finally с db.close() не нужен, async with закроет сессию сам! async def load_products_from_db(): """Загружает все товары из базы данных""" async with AsyncSessionLocal() as db: try: # Правильный асинхронный запрос в SQLAlchemy 2.0 stmt = select(DBProduct) result = await db.execute(stmt) db_products = result.scalars().all() products = [Product.from_db_record(p) for p in db_products] for i, p in enumerate(products): p.id = db_products[i].id print(f"✅ Загружено {len(products)} товаров из БД") return products except Exception as e: print(f"❌ Ошибка при загрузке товаров: {e}") return [] async def save_order_to_db(cart_items, total_price): """Сохраняет заказ в базу данных""" async with AsyncSessionLocal() as db: try: order = Order( date=datetime.now().strftime("%Y-%m-%d %H:%M:%S"), total_price=total_price ) db.add(order) await db.flush() # <-- await обязателен, чтобы получить order.id for product, quantity in cart_items.values(): order_item = OrderItem( order_id=order.id, product_id=product.id, quantity=quantity, price=product.price ) db.add(order_item) # Ищем товар в БД, чтобы обновить остаток stmt = select(DBProduct).where(DBProduct.id == product.id) result = await db.execute(stmt) db_product = result.scalar_one_or_none() if db_product: db_product.stock -= quantity await db.commit() # <-- await обязателен print(f"✅ Заказ #{order.id} сохранен в БД на сумму {total_price} руб.") return order.id except Exception as e: await db.rollback() print(f"❌ Ошибка при сохранении заказа: {e}") raise async def get_order_history(): """Получает историю всех заказов""" async with AsyncSessionLocal() as db: try: stmt = select(Order).order_by(Order.date.desc()) result = await db.execute(stmt) orders = result.scalars().all() print(f"✅ Загружено {len(orders)} заказов из БД") return orders except Exception as e: print(f"❌ Ошибка при загрузке заказов: {e}") return []