/
a_lukin
/
Labs_Python
Обзор
Документация
Войти
/
a_lukin
/
Labs_Python
Код
Запросы
2
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
lab6
lab6.py
306 строк
12 KB
a_lukin
create: lab6.py, 6-лаба_1.pdf, README.md
22 апр 2026, 22:29
Верифицирован
22 апр 2026, 22:29
b9e608b
Код
Авторство
О чём код?
""" Лабораторная работа №6 — Вариант 15 Музей: экспонаты, экскурсии, посетители Python + SQLite + SQLAlchemy ORM """ import os import shutil import datetime from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, UniqueConstraint from sqlalchemy.orm import declarative_base, relationship, sessionmaker DB_NAME = "museum.db" BACKUP_DIR = "backups_museum" engine = create_engine(f"sqlite:///{DB_NAME}", echo=False) Session = sessionmaker(bind=engine) session = Session() Base = declarative_base() # ── Модели (4 таблицы, 3 основные + связующая) ── class Экспонат(Base): __tablename__ = "экспонаты" id = Column(Integer, primary_key=True, autoincrement=True) название = Column(String, nullable=False) эпоха = Column(String, nullable=False) зал = Column(String, nullable=False) def __repr__(self): return f"[{self.id}] {self.название} — {self.эпоха} (зал {self.зал})" class Экскурсия(Base): __tablename__ = "экскурсии" id = Column(Integer, primary_key=True, autoincrement=True) тема = Column(String, nullable=False) гид = Column(String, nullable=False) время = Column(String, nullable=False) # например "12:00" посетители = relationship("ЗаписьНаЭкскурсию", back_populates="экскурсия") def __repr__(self): return f"[{self.id}] {self.тема} — гид {self.гид} ({self.время})" class Посетитель(Base): __tablename__ = "посетители" id = Column(Integer, primary_key=True, autoincrement=True) фио = Column(String, nullable=False) билет = Column(String, nullable=False) экскурсии = relationship("ЗаписьНаЭкскурсию", back_populates="посетитель") def __repr__(self): return f"[{self.id}] {self.фио} — билет {self.билет}" class ЗаписьНаЭкскурсию(Base): __tablename__ = "записи_на_экскурсии" id = Column(Integer, primary_key=True, autoincrement=True) экскурсия_id = Column(Integer, ForeignKey("экскурсии.id"), nullable=False) посетитель_id = Column(Integer, ForeignKey("посетители.id"), nullable=False) экскурсия = relationship("Экскурсия", back_populates="посетители") посетитель = relationship("Посетитель", back_populates="экскурсии") __table_args__ = (UniqueConstraint("экскурсия_id", "посетитель_id", name="unique_excursion_visitor"),) def __repr__(self): return f"[{self.id}] экскурсия {self.экскурсия_id} ← посетитель {self.посетитель_id}" Base.metadata.create_all(engine) # ── CRUD-функции ── def add_record(model, **kwargs): obj = model(**kwargs) session.add(obj) session.commit() print(f"✔ Добавлено: {obj}") def list_records(model): records = session.query(model).all() if not records: print(" (пусто)") for r in records: print(f" {r}") def update_record(model, record_id, **kwargs): obj = session.get(model, record_id) if not obj: print("✘ Запись не найдена"); return for k, v in kwargs.items(): setattr(obj, k, v) session.commit() print(f"✔ Обновлено: {obj}") def delete_record(model, record_id): obj = session.get(model, record_id) if not obj: print("✘ Запись не найдена"); return session.delete(obj) session.commit() print("✔ Удалено") # ── Поиск / фильтрация ── def search_exhibits(keyword): results = session.query(Экспонат).filter( (Экспонат.название.ilike(f"%{keyword}%")) | (Экспонат.эпоха.ilike(f"%{keyword}%")) | (Экспонат.зал.ilike(f"%{keyword}%")) ).all() print(f" Найдено {len(results)}:") for r in results: print(f" {r}") def search_excursions(keyword): results = session.query(Экскурсия).filter( (Экскурсия.тема.ilike(f"%{keyword}%")) | (Экскурсия.гид.ilike(f"%{keyword}%")) ).all() print(f" Найдено {len(results)}:") for r in results: print(f" {r}") def search_visitors(keyword): results = session.query(Посетитель).filter( (Посетитель.фио.ilike(f"%{keyword}%")) | (Посетитель.билет.ilike(f"%{keyword}%")) ).all() print(f" Найдено {len(results)}:") for r in results: print(f" {r}") def search_bookings(keyword): # поиск по ID экскурсии или посетителя try: num = int(keyword) results = session.query(ЗаписьНаЭкскурсию).filter( (ЗаписьНаЭкскурсию.экскурсия_id == num) | (ЗаписьНаЭкскурсию.посетитель_id == num) ).all() except ValueError: results = [] print(f" Найдено {len(results)}:") for r in results: print(f" {r}") # ── Резервное копирование / восстановление ── def backup(): os.makedirs(BACKUP_DIR, exist_ok=True) ts = datetime.datetime.now().strftime("%Y%m%d_%H%M%S") dest = os.path.join(BACKUP_DIR, f"backup_{ts}.db") shutil.copy2(DB_NAME, dest) print(f"✔ Резервная копия: {dest}") def restore(): if not os.path.isdir(BACKUP_DIR): print("✘ Папка backups_museum не найдена"); return files = sorted(os.listdir(BACKUP_DIR)) if not files: print("✘ Нет резервных копий"); return for i, f in enumerate(files, 1): print(f" {i}) {f}") idx = int(input("Номер копии: ")) - 1 src = os.path.join(BACKUP_DIR, files[idx]) session.close() shutil.copy2(src, DB_NAME) print(f"✔ Восстановлено из {files[idx]}") print(" Перезапустите программу.") exit() # ── Заполнение тестовыми данными ── def seed(): if session.query(Экспонат).count() > 0: print(" Данные уже есть, пропуск."); return # Экспонаты e1 = Экспонат(название="Саркофаг", эпоха="Древний Египет", зал="Зал 1") e2 = Экспонат(название="Амфора", эпоха="Античность", зал="Зал 2") e3 = Экспонат(название="Картина 'Звёздная ночь'", эпоха="XIX век", зал="Зал 3") session.add_all([e1, e2, e3]) # Экскурсии ex1 = Экскурсия(тема="Искусство Древнего Египта", гид="Иванова А.А.", время="10:00") ex2 = Экскурсия(тема="Шедевры живописи", гид="Петров В.С.", время="12:00") ex3 = Экскурсия(тема="Античные древности", гид="Сидорова М.И.", время="14:00") session.add_all([ex1, ex2, ex3]) session.flush() # Посетители v1 = Посетитель(фио="Смирнов Олег", билет="T001") v2 = Посетитель(фио="Кузнецова Анна", билет="T002") v3 = Посетитель(фио="Васильев Игорь", билет="T003") session.add_all([v1, v2, v3]) session.flush() # Записи на экскурсии session.add_all([ ЗаписьНаЭкскурсию(экскурсия_id=ex1.id, посетитель_id=v1.id), ЗаписьНаЭкскурсию(экскурсия_id=ex1.id, посетитель_id=v2.id), ЗаписьНаЭкскурсию(экскурсия_id=ex2.id, посетитель_id=v3.id), ЗаписьНаЭкскурсию(экскурсия_id=ex3.id, посетитель_id=v1.id), ]) session.commit() print("✔ Тестовые данные добавлены") # ── Меню ── TABLES = { "1": ("Экспонаты", Экспонат), "2": ("Экскурсии", Экскурсия), "3": ("Посетители", Посетитель), "4": ("Записи на экскурсии", ЗаписьНаЭкскурсию), } def input_fields(model): if model is Экспонат: return dict( название=input(" Название: "), эпоха=input(" Эпоха: "), зал=input(" Зал: ") ) elif model is Экскурсия: return dict( тема=input(" Тема: "), гид=input(" Гид: "), время=input(" Время (напр. 12:00): ") ) elif model is Посетитель: return dict( фио=input(" ФИО: "), билет=input(" Номер билета: ") ) else: # ЗаписьНаЭкскурсию return dict( экскурсия_id=int(input(" ID экскурсии: ")), посетитель_id=int(input(" ID посетителя: ")) ) def main(): seed() while True: print("\n═══════ МУЗЕЙ ═══════") print("1. Просмотр таблицы") print("2. Добавить запись") print("3. Обновить запись") print("4. Удалить запись") print("5. Поиск") print("6. Резервное копирование") print("7. Восстановление из копии") print("0. Выход") choice = input("► ") if choice == "0": break if choice in ("1", "2", "3", "4", "5"): print("Таблица: 1-Экспонаты 2-Экскурсии 3-Посетители 4-Записи на экскурсии") t = input("► ") if t not in TABLES: print("✘ Неверный выбор"); continue name, model = TABLES[t] if choice == "1": print(f"\n── {name} ──") list_records(model) elif choice == "2": add_record(model, **input_fields(model)) elif choice == "3": list_records(model) rid = int(input(" ID записи: ")) update_record(model, rid, **input_fields(model)) elif choice == "4": list_records(model) rid = int(input(" ID для удаления: ")) delete_record(model, rid) elif choice == "5": kw = input(" Ключевое слово: ") if model is Экспонат: search_exhibits(kw) elif model is Экскурсия: search_excursions(kw) elif model is Посетитель: search_visitors(kw) else: search_bookings(kw) elif choice == "6": backup() elif choice == "7": restore() if __name__ == "__main__": main()