从零搭建简易电商平台
本文是一份面向初学者的Python+MySQL电商平台开发教程。主要内容包括:1. 环境搭建与MySQL数据库设计,创建用户、商品、订单等核心表结构;2. Python连接MySQL的基础操作,包括连接对象和游标的使用;3. 用户系统的实现,包含密码加密、注册登录功能;4. 商品管理模块的CRUD操作;5. 订单系统的完整实现,涉及多表事务处理;6. 完整项目示例演示购物流程。教程强调数据库设计规
用 Python + MySQL
从零搭建电商平台
—— 零基础入门完整教程 ——
本文适合:初学者 | 涵盖:数据库设计 · Python连接 · CRUD · 用户系统
第一章 项目介绍与环境准备
1.1 项目概述
本教程将带你从零开始,使用 Python 和 MySQL 联合构建一个简单的电商平台后端系统。电商平台是日常生活中最常见的应用场景之一,涵盖了用户管理、商品管理、购物车和订单处理等核心功能,是学习数据库与后端编程结合的绝佳例子。
通过本教程,你将学会:
如何设计关系型数据库(MySQL)
如何用 Python 连接并操作 MySQL
如何实现用户注册和登录功能
如何对商品和订单进行增删改查(CRUD)操作
� 提示 本教程面向完全零基础的读者。每一步都有详细说明,请放心跟随学习!
1.2 技术栈说明
|
技术 |
用途说明 |
|
Python 3.x |
主要编程语言,负责业务逻辑处理 |
|
MySQL 8.x |
关系型数据库,存储所有数据 |
|
mysql-connector-python |
Python 连接 MySQL 的官方驱动库 |
|
hashlib |
Python 内置库,用于密码加密(MD5/SHA256) |
1.3 环境安装
安装 Python
访问 https://www.python.org/downloads/ 下载 Python 3.x 版本,安装时勾选 Add Python to PATH 选项。
安装完成后,打开命令行验证:
# 验证 Python 安装
python --version
# 应该显示类似:Python 3.11.0
安装 MySQL
访问 https://dev.mysql.com/downloads/mysql/ 下载并安装 MySQL 8.x。安装时请牢记设置的 root 密码。
安装 Python MySQL 驱动
打开命令行(终端),执行以下命令安装连接库:
pip install mysql-connector-python
� 提示 如果安装缓慢,可以使用国内镜像:pip install mysql-connector-python -i https://pypi.tuna.tsinghua.edu.cn/simple
第二章 数据库设计与建表
2.1 数据库设计思路
一个电商平台至少需要以下四张核心表:
|
表名 |
中文名 |
存储内容 |
|
users |
用户表 |
用户基本信息、密码 |
|
products |
商品表 |
商品名称、价格、库存 |
|
orders |
订单表 |
谁购买了什么、金额 |
|
order_items |
订单明细表 |
每个订单包含的具体商品 |
这四张表之间有明确的关联关系:一个用户可以有多个订单,一个订单可以包含多件商品,这就是关系型数据库的核心思想。
2.2 创建数据库
打开 MySQL 命令行(或 MySQL Workbench),执行以下 SQL 语句创建数据库:
-- 创建电商数据库
CREATE DATABASE IF NOT EXISTS ecommerce
CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
-- 切换到该数据库
USE ecommerce;
� 提示 utf8mb4 是 MySQL 中最完整的 UTF-8 字符集,支持中文、Emoji 等所有字符,推荐使用。
2.3 创建用户表(users)
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY, -- 主键,自增
username VARCHAR(50) NOT NULL UNIQUE, -- 用户名,不可重复
password VARCHAR(64) NOT NULL, -- 加密后的密码
email VARCHAR(100) NOT NULL UNIQUE, -- 邮箱,不可重复
created_at DATETIME DEFAULT CURRENT_TIMESTAMP -- 注册时间
);
字段说明:
id:主键(PRIMARY KEY),每个用户唯一标识,AUTO_INCREMENT 代表自动递增
username:用户名,UNIQUE 约束确保不会有重复用户名
password:密码存储的是加密后的字符串,绝不存明文
created_at:用 DEFAULT CURRENT_TIMESTAMP 让 MySQL 自动填写注册时间
2.4 创建商品表(products)
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(200) NOT NULL, -- 商品名称
description TEXT, -- 商品描述
price DECIMAL(10, 2) NOT NULL, -- 价格(精确到分)
stock INT DEFAULT 0, -- 库存数量
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
� 提示 价格使用 DECIMAL(10, 2) 而不是 FLOAT,是因为浮点数在计算机中有精度误差,涉及金钱必须用 DECIMAL。
2.5 创建订单表(orders)
CREATE TABLE orders (
id INT AUTO_INCREMENT PRIMARY KEY,
user_id INT NOT NULL, -- 关联用户
total_amount DECIMAL(10, 2) NOT NULL, -- 订单总金额
status ENUM('pending','paid','cancelled') -- 订单状态
DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) -- 外键约束
);
这里引入了两个重要概念:
ENUM:枚举类型,限定字段只能是几个固定值之一,防止输入错误数据
FOREIGN KEY(外键):确保 user_id 必须在 users 表中存在,保证数据完整性
2.6 创建订单明细表(order_items)
CREATE TABLE order_items (
id INT AUTO_INCREMENT PRIMARY KEY,
order_id INT NOT NULL,
product_id INT NOT NULL,
quantity INT NOT NULL, -- 购买数量
unit_price DECIMAL(10, 2) NOT NULL, -- 下单时的单价
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (product_id) REFERENCES products(id)
);
� 提示 为什么要单独存 unit_price?因为商品价格可能随时变动,订单明细需要记录下单那一刻的价格,这是电商系统的重要设计原则。
第三章 Python 连接 MySQL
3.1 建立数据库连接
创建一个名为 db_config.py 的文件,专门管理数据库连接:
# db_config.py
import mysql.connector
def get_connection():
"""获取数据库连接"""
connection = mysql.connector.connect(
host = 'localhost', # 数据库服务器地址
user = 'root', # 数据库用户名
password = '你的密码', # 数据库密码
database = 'ecommerce', # 使用的数据库名
charset = 'utf8mb4'
)
return connection
# 测试连接
if __name__ == '__main__':
conn = get_connection()
print('数据库连接成功!')
conn.close()
运行测试:
python db_config.py
# 输出:数据库连接成功!
� 提示 将数据库配置单独放在一个文件中是良好的编程习惯,方便后续修改,也避免密码散落在代码各处。
3.2 连接的核心概念
Python 操作 MySQL 时,需要理解两个核心对象:
|
对象 |
名称 |
作用 |
|
connection |
连接对象 |
代表与数据库的连接通道,负责提交/回滚 |
|
cursor |
游标对象 |
用于执行 SQL 语句和获取结果 |
conn = get_connection() # 建立连接
cursor = conn.cursor() # 创建游标
cursor.execute('SELECT ...') # 执行 SQL
result = cursor.fetchall() # 获取所有结果
conn.commit() # 提交事务(增删改需要)
cursor.close() # 关闭游标
conn.close() # 关闭连接
第四章 用户注册与登录
4.1 密码加密原理
存储密码时,注意绝对不能存明文!大家想象一下,如果数据库被黑客攻击,所有用户的密码都会泄露。正确的做法是使用哈希算法对密码进行单向加密。
本教程使用 SHA-256 算法:
SHA-256 是单向的:给定密码可以生成哈希值,但无法从哈希值反推密码
相同的密码总是产生相同的哈希值,因此验证时只需对比哈希值即可
# 密码加密示例
import hashlib
def hash_password(password: str) -> str:
"""对密码进行 SHA-256 加密"""
return hashlib.sha256(password.encode('utf-8')).hexdigest()
# 测试
print(hash_password('mypassword123'))
# 输出:加密后的64位十六进制字符串
4.2 用户注册功能
创建 user_service.py 文件,实现注册功能:
# user_service.py
import hashlib
from db_config import get_connection
def hash_password(password: str) -> str:
return hashlib.sha256(password.encode('utf-8')).hexdigest()
def register_user(username: str, password: str, email: str):
"""用户注册"""
conn = get_connection()
cursor = conn.cursor()
try:
sql = """
INSERT INTO users (username, password, email)
VALUES (%s, %s, %s)
"""
hashed_pwd = hash_password(password)
cursor.execute(sql, (username, hashed_pwd, email))
conn.commit()
print(f'用户 {username} 注册成功!')
return True
except Exception as e:
conn.rollback() # 出错则回滚
print(f'注册失败:{e}')
return False
finally:
cursor.close()
conn.close()
� 提示 注意 SQL 语句中使用 %s 占位符而非直接拼接字符串,这是防止 SQL 注入攻击的关键!永远不要写 f"... WHERE name='{user_input}'" 这样的代码。
4.3 用户登录功能
def login_user(username: str, password: str):
"""用户登录,验证成功返回用户信息,否则返回 None"""
conn = get_connection()
cursor = conn.cursor(dictionary=True) # 返回字典格式
try:
sql = 'SELECT * FROM users WHERE username = %s'
cursor.execute(sql, (username,))
user = cursor.fetchone() # 获取一条记录
if user is None:
print('用户不存在')
return None
# 比对密码哈希
if user['password'] == hash_password(password):
print(f'欢迎回来,{username}!')
return user
else:
print('密码错误')
return None
finally:
cursor.close()
conn.close()
# ── 测试 ──────────────────────────────────────
if __name__ == '__main__':
register_user('alice', 'abc123', 'alice@example.com')
user = login_user('alice', 'abc123')
print(user)
第五章 商品管理(CRUD 操作)
CRUD 是四种基本数据库操作的缩写:Create(新增)、Read(查询)、Update(修改)、Delete(删除)。几乎所有软件都离不开这四种操作。
5.1 新增商品(Create)
# product_service.py
from db_config import get_connection
def add_product(name: str, price: float,
stock: int, description: str = ''):
"""新增商品"""
conn = get_connection()
cursor = conn.cursor()
try:
sql = """
INSERT INTO products (name, price, stock, description)
VALUES (%s, %s, %s, %s)
"""
cursor.execute(sql, (name, price, stock, description))
conn.commit()
product_id = cursor.lastrowid # 获取刚插入记录的ID
print(f'商品已添加,ID = {product_id}')
return product_id
except Exception as e:
conn.rollback()
print(f'添加失败:{e}')
return None
finally:
cursor.close()
conn.close()
5.2 查询商品(Read)
def get_all_products():
"""获取所有商品列表"""
conn = get_connection()
cursor = conn.cursor(dictionary=True)
try:
cursor.execute('SELECT * FROM products ORDER BY id')
products = cursor.fetchall()
return products
finally:
cursor.close()
conn.close()
def get_product_by_id(product_id: int):
"""根据ID查询单个商品"""
conn = get_connection()
cursor = conn.cursor(dictionary=True)
try:
cursor.execute('SELECT * FROM products WHERE id = %s',
(product_id,))
return cursor.fetchone() # 返回一条或 None
finally:
cursor.close()
conn.close()
5.3 修改商品(Update)
def update_product_price(product_id: int, new_price: float):
"""修改商品价格"""
conn = get_connection()
cursor = conn.cursor()
try:
sql = 'UPDATE products SET price = %s WHERE id = %s'
cursor.execute(sql, (new_price, product_id))
conn.commit()
if cursor.rowcount > 0:
print(f'商品 {product_id} 价格已更新为 {new_price}')
else:
print('商品不存在')
except Exception as e:
conn.rollback()
print(f'更新失败:{e}')
finally:
cursor.close()
conn.close()
5.4 删除商品(Delete)
def delete_product(product_id: int):
"""删除商品"""
conn = get_connection()
cursor = conn.cursor()
try:
cursor.execute('DELETE FROM products WHERE id = %s',
(product_id,))
conn.commit()
if cursor.rowcount > 0:
print(f'商品 {product_id} 已删除')
else:
print('商品不存在')
except Exception as e:
conn.rollback()
print(f'删除失败:{e}')
finally:
cursor.close()
conn.close()
� 提示 cursor.rowcount 表示上一条 SQL 影响了多少行数据,通过它可以判断操作是否真正修改了数据库。
第六章 订单管理
6.1 创建订单
创建订单是电商系统中最复杂的操作,涉及多张表的同时写入,以及库存扣减。必须使用事务(Transaction)保证原子性——要么全部成功,要么全部失败。
# order_service.py
from db_config import get_connection
def create_order(user_id: int, cart: list):
"""
创建订单
cart 格式:[{'product_id': 1, 'quantity': 2}, ...]
"""
conn = get_connection()
cursor = conn.cursor(dictionary=True)
try:
total_amount = 0
items_to_insert = []
# 第一步:检查库存并计算总价
for item in cart:
cursor.execute(
'SELECT id, name, price, stock FROM products WHERE id = %s',
(item['product_id'],)
)
product = cursor.fetchone()
if product is None:
raise ValueError(f"商品 {item['product_id']} 不存在")
if product['stock'] < item['quantity']:
raise ValueError(f"{product['name']} 库存不足")
total_amount += product['price'] * item['quantity']
items_to_insert.append({
'product_id': product['id'],
'quantity': item['quantity'],
'unit_price': product['price'],
'stock': product['stock']
})
# 第二步:创建订单主记录
cursor.execute(
'INSERT INTO orders (user_id, total_amount) VALUES (%s, %s)',
(user_id, total_amount)
)
order_id = cursor.lastrowid
# 第三步:插入订单明细 + 扣减库存
for it in items_to_insert:
cursor.execute(
'INSERT INTO order_items (order_id, product_id, quantity, unit_price)'
' VALUES (%s, %s, %s, %s)',
(order_id, it['product_id'], it['quantity'], it['unit_price'])
)
cursor.execute(
'UPDATE products SET stock = stock - %s WHERE id = %s',
(it['quantity'], it['product_id'])
)
conn.commit() # 全部成功才提交
print(f'订单创建成功,订单ID = {order_id},总金额 = {total_amount:.2f}')
return order_id
except Exception as e:
conn.rollback() # 任何错误都回滚
print(f'订单创建失败:{e}')
return None
finally:
cursor.close()
conn.close()
6.2 查询用户订单
def get_user_orders(user_id: int):
"""查询用户的所有订单(含明细)"""
conn = get_connection()
cursor = conn.cursor(dictionary=True)
try:
# 查询订单列表
cursor.execute(
'SELECT * FROM orders WHERE user_id = %s ORDER BY created_at DESC',
(user_id,)
)
orders = cursor.fetchall()
# 为每个订单查询明细
for order in orders:
cursor.execute(
'''SELECT oi.quantity, oi.unit_price, p.name
FROM order_items oi
JOIN products p ON oi.product_id = p.id
WHERE oi.order_id = %s''',
(order['id'],)
)
order['items'] = cursor.fetchall()
return orders
finally:
cursor.close()
conn.close()
� 提示 这里使用了 JOIN 连接查询,将 order_items 和 products 两张表的数据合并,一次查询获取商品名称和价格,避免多次往返数据库。
第七章 完整运行示例
7.1 主程序入口
创建 main.py 将所有功能串联起来,模拟一次完整的购物流程:
# main.py
from user_service import register_user, login_user
from product_service import add_product, get_all_products
from order_service import create_order, get_user_orders
print('=' * 50)
print(' 欢迎使用电商平台演示系统')
print('=' * 50)
# ── 1. 用户注册与登录 ──
register_user('张三', 'password123', 'zhangsan@example.com')
user = login_user('张三', 'password123')
# ── 2. 添加商品 ──
add_product('Python编程书', 59.90, 100, '零基础入门到精通')
add_product('机械键盘', 299.00, 50, '青轴,手感极佳')
add_product('USB集线器', 39.90, 200, '4口USB3.0')
# ── 3. 展示商品列表 ──
print('\n当前商品列表:')
for p in get_all_products():
print(f" [{p['id']}] {p['name']} ¥{p['price']} 库存:{p['stock']}")
# ── 4. 下订单 ──
cart = [
{'product_id': 1, 'quantity': 2},
{'product_id': 3, 'quantity': 1},
]
order_id = create_order(user['id'], cart)
# ── 5. 查看订单 ──
print('\n我的订单:')
for order in get_user_orders(user['id']):
print(f" 订单#{order['id']} 总价:¥{order['total_amount']} 状态:{order['status']}")
for item in order['items']:
print(f" - {item['name']} x{item['quantity']} @¥{item['unit_price']}")
7.2 项目文件结构
ecommerce/
├── db_config.py # 数据库连接配置
├── user_service.py # 用户注册/登录
├── product_service.py # 商品 CRUD
├── order_service.py # 订单管理
└── main.py # 主程序入口
第八章 总结与延伸学习
|
知识点 |
掌握内容 |
|
数据库设计 |
四张核心表,主键/外键/约束的使用 |
|
Python 连接 MySQL |
mysql-connector,连接对象与游标 |
|
SQL 防注入 |
使用 %s 占位符,避免字符串拼接 |
|
密码安全 |
SHA-256 单向加密,绝不存明文 |
|
CRUD 操作 |
商品的增删改查完整实现 |
|
事务处理 |
commit() 与 rollback() 保证数据完整性 |
|
JOIN 查询 |
多表联查获取关联数据 |
感谢阅读!如有问题欢迎在评论区留言交流 �
更多推荐

所有评论(0)