当前位置: 首页 > news >正文

Python实战:基于控制台与MySQL的电影票预订系统开发指南

前言

在当今数字化时代,电影票预订系统已经成为影院管理的核心工具。本文将通过Python与MySQL的结合,带你从零开始开发一个功能完整的控制台版电影票预订系统。这个项目不仅涵盖了Python基础语法和MySQL数据库操作,还涉及面向对象编程、异常处理等核心概念,是提升Python实战能力的绝佳练习。

一、系统设计与功能规划

1.1 系统架构设计

我们的电影票预订系统将采用三层架构:

  • 表示层:控制台界面(后期可扩展为Web或GUI)

  • 业务逻辑层:处理核心业务规则

  • 数据访问层:负责与MySQL数据库交互

1.2 核心功能模块

1. 用户管理- 注册/登录/注销- 个人信息管理2. 电影管理- 电影信息查询- 电影排期查看3. 票务管理- 选座购票- 订单查询- 退票改签4. 管理员功能- 电影信息维护- 场次安排- 销售统计

二、数据库设计与实现

2.1 MySQL表结构设计

用户表(users)

CREATE TABLE users (user_id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,password VARCHAR(100) NOT NULL,real_name VARCHAR(50),phone VARCHAR(20),email VARCHAR(100),is_admin BOOLEAN DEFAULT FALSE,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

电影表(movies)

CREATE TABLE movies (movie_id INT AUTO_INCREMENT PRIMARY KEY,title VARCHAR(100) NOT NULL,director VARCHAR(50),actors VARCHAR(200),genre VARCHAR(50),duration INT COMMENT '分钟',release_date DATE,description TEXT,poster_url VARCHAR(255)
);

放映场次表(screenings)

CREATE TABLE screenings (screening_id INT AUTO_INCREMENT PRIMARY KEY,movie_id INT NOT NULL,theater_id INT NOT NULL,start_time DATETIME NOT NULL,end_time DATETIME NOT NULL,price DECIMAL(10,2) NOT NULL,available_seats INT NOT NULL,FOREIGN KEY (movie_id) REFERENCES movies(movie_id),FOREIGN KEY (theater_id) REFERENCES theaters(theater_id)
);

订单表(orders)

CREATE TABLE orders (order_id INT AUTO_INCREMENT PRIMARY KEY,user_id INT NOT NULL,screening_id INT NOT NULL,seat_count INT NOT NULL,total_amount DECIMAL(10,2) NOT NULL,status ENUM('pending', 'paid', 'cancelled') DEFAULT 'pending',created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,FOREIGN KEY (user_id) REFERENCES users(user_id),FOREIGN KEY (screening_id) REFERENCES screenings(screening_id)
);

2.2 数据库连接工具类

import mysql.connector
from mysql.connector import Errorclass Database:def __init__(self, host='localhost', database='movie_booking', user='root', password='password'):self.host = hostself.database = databaseself.user = userself.password = passwordself.connection = Nonedef connect(self):try:self.connection = mysql.connector.connect(host=self.host,database=self.database,user=self.user,password=self.password)return Trueexcept Error as e:print(f"数据库连接失败: {e}")return Falsedef disconnect(self):if self.connection and self.connection.is_connected():self.connection.close()def execute_query(self, query, params=None, fetch=False):cursor = Nonetry:cursor = self.connection.cursor(dictionary=True)cursor.execute(query, params or ())if fetch:return cursor.fetchall()else:self.connection.commit()return cursor.rowcountexcept Error as e:print(f"数据库操作失败: {e}")return Nonefinally:if cursor: cursor.close()

三、核心功能实现

3.1 用户认证模块

import hashlibclass UserService:def __init__(self, db):self.db = dbdef register(self, username, password, **kwargs):# 检查用户名是否存在if self.get_user_by_username(username):return False, "用户名已存在"# 密码加密hashed_pwd = self._hash_password(password)# 插入用户数据query = """INSERT INTO users (username, password, real_name, phone, email) VALUES (%s, %s, %s, %s, %s)"""params = (username, hashed_pwd, kwargs.get('real_name'), kwargs.get('phone'), kwargs.get('email'))if self.db.execute_query(query, params):return True, "注册成功"return False, "注册失败"def login(self, username, password):user = self.get_user_by_username(username)if not user:return None, "用户不存在"if self._verify_password(password, user['password']):return user, "登录成功"return None, "密码错误"def get_user_by_username(self, username):query = "SELECT * FROM users WHERE username = %s"result = self.db.execute_query(query, (username,), fetch=True)return result[0] if result else Nonedef _hash_password(self, password):return hashlib.sha256(password.encode()).hexdigest()def _verify_password(self, input_pwd, hashed_pwd):return self._hash_password(input_pwd) == hashed_pwd

3.2 电影管理模块

class MovieService:def __init__(self, db):self.db = dbdef add_movie(self, title, director, actors, genre, duration, release_date, description, poster_url):query = """INSERT INTO movies (title, director, actors, genre, duration, release_date, description, poster_url)VALUES (%s, %s, %s, %s, %s, %s, %s, %s)"""params = (title, director, actors, genre, duration, release_date, description, poster_url)return self.db.execute_query(query, params)def get_all_movies(self):query = "SELECT * FROM movies ORDER BY release_date DESC"return self.db.execute_query(query, fetch=True)def get_movie_by_id(self, movie_id):query = "SELECT * FROM movies WHERE movie_id = %s"result = self.db.execute_query(query, (movie_id,), fetch=True)return result[0] if result else Nonedef search_movies(self, keyword):query = """SELECT * FROM movies WHERE title LIKE %s OR director LIKE %s OR actors LIKE %s"""params = (f"%{keyword}%", f"%{keyword}%", f"%{keyword}%")return self.db.execute_query(query, params, fetch=True)

3.3 票务管理模块

from datetime import datetimeclass BookingService:def __init__(self, db):self.db = dbdef get_available_screenings(self, movie_id=None):query = """SELECT s.*, m.title, m.duration, t.name as theater_nameFROM screenings sJOIN movies m ON s.movie_id = m.movie_idJOIN theaters t ON s.theater_id = t.theater_idWHERE s.start_time > %s AND s.available_seats > 0"""params = [datetime.now()]if movie_id:query += " AND s.movie_id = %s"params.append(movie_id)query += " ORDER BY s.start_time"return self.db.execute_query(query, params, fetch=True)def book_tickets(self, user_id, screening_id, seat_count):# 检查场次和座位screening = self.get_screening_by_id(screening_id)if not screening or screening['available_seats'] < seat_count:return False, "座位不足"# 计算总价total_amount = screening['price'] * seat_count# 创建订单order_query = """INSERT INTO orders (user_id, screening_id, seat_count, total_amount)VALUES (%s, %s, %s, %s)"""order_params = (user_id, screening_id, seat_count, total_amount)# 更新场次座位screening_query = """UPDATE screenings SET available_seats = available_seats - %sWHERE screening_id = %s"""screening_params = (seat_count, screening_id)# 事务处理try:self.db.connection.start_transaction()self.db.execute_query(order_query, order_params)self.db.execute_query(screening_query, screening_params)self.db.connection.commit()return True, "订票成功"except Exception as e:self.db.connection.rollback()return False, f"订票失败: {e}"def get_user_orders(self, user_id):query = """SELECT o.*, m.title, s.start_time, t.name as theater_nameFROM orders oJOIN screenings s ON o.screening_id = s.screening_idJOIN movies m ON s.movie_id = m.movie_idJOIN theaters t ON s.theater_id = t.theater_idWHERE o.user_id = %sORDER BY o.created_at DESC"""return self.db.execute_query(query, (user_id,), fetch=True)def cancel_order(self, order_id):# 获取订单信息order_query = """SELECT o.*, s.screening_id, o.seat_countFROM orders oJOIN screenings s ON o.screening_id = s.screening_idWHERE o.order_id = %s AND o.status = 'paid'"""order = self.db.execute_query(order_query, (order_id,), fetch=True)if not order:return False, "订单不存在或不可取消"order = order[0]# 事务处理try:self.db.connection.start_transaction()# 更新订单状态update_order = """UPDATE orders SET status = 'cancelled' WHERE order_id = %s"""self.db.execute_query(update_order, (order_id,))# 恢复座位update_screening = """UPDATE screenings SET available_seats = available_seats + %sWHERE screening_id = %s"""self.db.execute_query(update_screening, (order['seat_count'], order['screening_id']))self.db.connection.commit()return True, "退票成功"except Exception as e:self.db.connection.rollback()return False, f"退票失败: {e}"

四、控制台界面实现

4.1 主菜单与导航

class ConsoleUI:def __init__(self):self.db = Database()if not self.db.connect():raise Exception("无法连接数据库")self.user_service = UserService(self.db)self.movie_service = MovieService(self.db)self.booking_service = BookingService(self.db)self.current_user = Nonedef run(self):while True:if not self.current_user:self.show_main_menu()else:if self.current_user['is_admin']:self.show_admin_menu()else:self.show_user_menu()def show_main_menu(self):print("\n=== 电影票预订系统 ===")print("1. 登录")print("2. 注册")print("3. 查看电影")print("0. 退出")choice = input("请选择: ")if choice == "1":self.login()elif choice == "2":self.register()elif choice == "3":self.show_movies()elif choice == "0":exit()else:print("无效选择")def show_user_menu(self):print(f"\n=== 欢迎, {self.current_user['username']} ===")print("1. 查看电影")print("2. 查询场次")print("3. 我的订单")print("4. 个人信息")print("0. 注销")choice = input("请选择: ")if choice == "1":self.show_movies()elif choice == "2":self.show_screenings()elif choice == "3":self.show_user_orders()elif choice == "4":self.show_user_profile()elif choice == "0":self.current_user = Noneelse:print("无效选择")def show_admin_menu(self):print(f"\n=== 管理员面板 ===")print("1. 电影管理")print("2. 场次管理")print("3. 销售统计")print("0. 注销")choice = input("请选择: ")if choice == "1":self.manage_movies()elif choice == "2":self.manage_screenings()elif choice == "3":self.view_sales_report()elif choice == "0":self.current_user = Noneelse:print("无效选择")

4.2 用户交互功能实现

    def login(self):print("\n=== 用户登录 ===")username = input("用户名: ")password = input("密码: ")user, message = self.user_service.login(username, password)if user:self.current_user = userprint(f"登录成功,欢迎 {user['username']}!")else:print(f"登录失败: {message}")def register(self):print("\n=== 用户注册 ===")username = input("用户名: ")password = input("密码: ")real_name = input("真实姓名(可选): ")phone = input("电话(可选): ")email = input("邮箱(可选): ")success, message = self.user_service.register(username, password, real_name=real_name, phone=phone, email=email)print(message)def show_movies(self):movies = self.movie_service.get_all_movies()print("\n=== 电影列表 ===")for idx, movie in enumerate(movies, 1):print(f"{idx}. {movie['title']} ({movie['release_date'].year})")print(f"   导演: {movie['director']} 类型: {movie['genre']}")print(f"   时长: {movie['duration']}分钟")choice = input("\n输入电影编号查看详情(0返回): ")if choice.isdigit() and int(choice) > 0:movie = movies[int(choice)-1]self.show_movie_detail(movie['movie_id'])def show_movie_detail(self, movie_id):movie = self.movie_service.get_movie_by_id(movie_id)if not movie:print("电影不存在")returnprint(f"\n=== {movie['title']} ===")print(f"导演: {movie['director']}")print(f"主演: {movie['actors']}")print(f"类型: {movie['genre']} 时长: {movie['duration']}分钟")print(f"上映日期: {movie['release_date']}")print("\n剧情简介:")print(movie['description'])screenings = self.booking_service.get_available_screenings(movie_id)if screenings:print("\n=== 放映场次 ===")for idx, s in enumerate(screenings, 1):print(f"{idx}. {s['start_time']} {s['theater_name']} "f"¥{s['price']} 剩余座位: {s['available_seats']}")if self.current_user:choice = input("\n输入场次编号订票(0返回): ")if choice.isdigit() and int(choice) > 0:self.book_ticket(screenings[int(choice)-1]['screening_id'])def book_ticket(self, screening_id):screening = self.booking_service.get_screening_by_id(screening_id)if not screening:print("场次不存在")returnprint(f"\n=== 订票: {screening['title']} ===")print(f"时间: {screening['start_time']}")print(f"影院: {screening['theater_name']}")print(f"价格: ¥{screening['price']}/张 剩余座位: {screening['available_seats']}")while True:seat_count = input("请输入购票数量: ")if seat_count.isdigit() and 0 < int(seat_count) <= screening['available_seats']:breakprint("输入无效或座位不足")success, message = self.booking_service.book_tickets(self.current_user['user_id'], screening_id, int(seat_count))print(message)

五、项目扩展与优化

5.1 功能扩展建议

  1. 座位选择:实现具体座位图选择而非简单计数

  2. 支付集成:模拟支付流程

  3. 会员积分:增加会员等级和积分系统

  4. 评价系统:允许用户对电影评分和评论

5.2 代码优化方向

  1. 使用ORM:引入SQLAlchemy替代原生SQL

  2. 日志记录:添加操作日志记录

  3. 配置管理:将数据库配置等移出代码

  4. 异常处理:增强异常捕获和用户友好提示

5.3 部署与打包

  1. 可执行文件:使用PyInstaller打包为exe

  2. 安装脚本:编写数据库初始化脚本

  3. Docker支持:添加Dockerfile方便部署

结语

通过这个电影票预订系统项目,我们完整实践了:

  1. Python控制台程序开发

  2. MySQL数据库设计与操作

  3. 面向对象的业务逻辑实现

  4. 完整的用户交互流程

进一步学习建议

  1. 尝试使用Tkinter或PyQt添加图形界面

  2. 学习使用Flask/Django转为Web应用

  3. 研究数据库连接池优化性能

  4. 添加单元测试保证代码质量

如果你在实现过程中遇到任何问题,欢迎在评论区留言讨论。觉得本文有帮助的话,请点赞收藏支持!

http://www.xdnf.cn/news/288577.html

相关文章:

  • 学习路线(机器人系统)
  • 模糊控制理论(含仿真)
  • 7400MB/s5050TBW完美结合,全新希捷酷玩530R SSD体验评测
  • 10 种最新的思维链(Chain-of-Thought, CoT)增强方法
  • 攻防世界-php伪协议和文件包含
  • 第一章-Rust入门
  • 音频感知动画新纪元:Sonic让你的作品更生动
  • PE文件结构(导出表)
  • 专家系统的推理流程深度解析
  • Java SE(8)——继承
  • 虚拟dom是什么,他有什么好处
  • 深度学习里程碑:AlexNet 架构解析与核心技术详解
  • 【深度学习|学习笔记】Deep Belief Network(DBN,深度置信网络)起源、原理、发展和应用(附代码)
  • 【KWDB 创作者计划】基于 ESP32 + KWDB 的智能环境监测系统实战
  • 高可用架构设计——故障响应
  • Red Hat6.4环境下搭建DHCP服务器
  • 第六章 流量特征分析-蚁剑流量分析(玄机靶场系列)
  • MCP原理详解及实战案例(动嘴出UI稿、3D建模)
  • Linux系统安装PaddleDetection
  • 基于CBOW模型的词向量训练实战:从原理到PyTorch实现
  • 使用AI 将文本转成视频 工具 介绍
  • 实验-数字电路设计2-复用器和七段数码管(数字逻辑)
  • 在Ubuntu系统中安装桌面环境
  • 路由器详细讲解
  • Docker —— 隔离的基本操作(1)
  • SpringCloud GateWay网关
  • 排序用法(Arrays.sort)
  • AI笔记-1
  • Qwen2_5-Omni-3B:支持视频、音频、图像和文本的全能AI,可在本地运行
  • 【Flask】ORM模型以及数据库迁移的两种方法(flask-migrate、Alembic)