<think>我们使用FastAPI框架来构建后端,并使用SQLAlchemy作为ORM,Alembic进行数据库迁移。首先,我们需要安装必要的依赖。在requirements.txt中列出:然后,按照目录结构创建文件。下面我们逐个文件编写代码。1.首先,配置数据库连接和基础设置(core/config.py):2.定义数据库基类(db/base.py)和数据库会话(db/__init__.py)3.定义模型(models/models.py)4.定义Pydantic模型(schemas/schemas.py)5.通用CRUD操作(crud/base.py)6.API路由(api/api.py)7.主程序入口(main.py)8.数据库迁移配置(alembic.ini)和迁移环境(db/migrations/env.py等)可以通过`alembicinit`生成,然后修改配置。由于alembic.ini和迁移环境需要初始化生成,这里我们先不写,但会说明如何修改。下面开始编写代码:</think>下面是一个基于MySQL的仓库管理系统的Python后端实现,采用FastAPI + SQLAlchemy架构:
### 文件结构实现代码
#### 1. `core/config.py` - 配置文件
```python
from pydantic import BaseSettings
class Settings(BaseSettings):
DATABASE_URL: str = "mysql+pymysql://user:password@localhost:3306/warehouse"
SECRET_KEY: str = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
class Config:
env_file = ".env"
settings = Settings()
```
#### 2. `db/base.py` - ORM基类
```python
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
```
#### 3. `db/__init__.py` - 数据库会话
```python
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from core.config import settings
engine = create_engine(
settings.DATABASE_URL,
pool_pre_ping=True,
pool_recycle=3600
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
```
#### 4. `models/models.py` - 数据模型
```python
from sqlalchemy import Column, Integer, String, Float, ForeignKey
from db.base import Base
class Product(Base):
__tablename__ = "products"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(100), index=True, nullable=False)
description = Column(String(255))
price = Column(Float, nullable=False)
quantity = Column(Integer, default=0)
category = Column(String(50), index=True)
class Location(Base):
__tablename__ = "locations"
id = Column(Integer, primary_key=True, index=True)
name = Column(String(50), unique=True, nullable=False)
description = Column(String(255))
class Inventory(Base):
__tablename__ = "inventory"
product_id = Column(Integer, ForeignKey("products.id"), primary_key=True)
location_id = Column(Integer, ForeignKey("locations.id"), primary_key=True)
quantity = Column(Integer, default=0)
```
#### 5. `schemas/schemas.py` - Pydantic模型
```python
from pydantic import BaseModel
from typing import Optional
class ProductCreate(BaseModel):
name: str
description: Optional[str] = None
price: float
quantity: int
category: str
class Product(ProductCreate):
id: int
class Config:
orm_mode = True
class LocationCreate(BaseModel):
name: str
description: Optional[str] = None
class Location(LocationCreate):
id: int
class Config:
orm_mode = True
class InventoryUpdate(BaseModel):
product_id: int
location_id: int
quantity: int
class Inventory(InventoryUpdate):
class Config:
orm_mode = True
```
#### 6. `crud/base.py` - CRUD操作
```python
from typing import Type, TypeVar, Generic, List
from sqlalchemy.orm import Session
from db.base import Base
ModelType = TypeVar("ModelType", bound=Base)
class CRUDBase(Generic[ModelType]):
def __init__(self, model: Type[ModelType]):
self.model = model
def get(self, db: Session, id: int) -> ModelType:
return db.query(self.model).filter(self.model.id == id).first()
def get_multi(self, db: Session, skip: int = 0, limit: int = 100) -> List[ModelType]:
return db.query(self.model).offset(skip).limit(limit).all()
def create(self, db: Session, obj_in) -> ModelType:
db_obj = self.model(**obj_in.dict())
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def update(self, db: Session, db_obj: ModelType, obj_in) -> ModelType:
update_data = obj_in.dict(exclude_unset=True)
for field in update_data:
setattr(db_obj, field, update_data[field])
db.add(db_obj)
db.commit()
db.refresh(db_obj)
return db_obj
def delete(self, db: Session, id: int) -> ModelType:
obj = db.query(self.model).get(id)
db.delete(obj)
db.commit()
return obj
class CRUDInventory(CRUDBase):
def update_inventory(self, db: Session, inventory_in) -> ModelType:
# 检查库存记录是否存在
inventory = db.query(self.model).filter(
self.model.product_id == inventory_in.product_id,
self.model.location_id == inventory_in.location_id
).first()
if inventory:
# 更新现有库存
inventory.quantity = inventory_in.quantity
else:
# 创建新库存记录
inventory = self.model(**inventory_in.dict())
db.add(inventory)
db.commit()
db.refresh(inventory)
return inventory
# 实例化CRUD类
crud_product = CRUDBase(Product)
crud_location = CRUDBase(Location)
crud_inventory = CRUDInventory(Inventory)
```
#### 7. `api/api.py` - API路由
```python
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from db import get_db
from crud import crud_product, crud_location, crud_inventory
from schemas import Product, ProductCreate, Location, LocationCreate, InventoryUpdate
router = APIRouter()
# 产品路由
@router.post("/products/", response_model=Product)
def create_product(product: ProductCreate, db: Session = Depends(get_db)):
return crud_product.create(db, obj_in=product)
@router.get("/products/{product_id}", response_model=Product)
def read_product(product_id: int, db: Session = Depends(get_db)):
product = crud_product.get(db, id=product_id)
if not product:
raise HTTPException(status_code=404, detail="Product not found")
return product
# 位置路由
@router.post("/locations/", response_model=Location)
def create_location(location: LocationCreate, db: Session = Depends(get_db)):
return crud_location.create(db, obj_in=location)
@router.get("/locations/{location_id}", response_model=Location)
def read_location(location_id: int, db: Session = Depends(get_db)):
location = crud_location.get(db, id=location_id)
if not location:
raise HTTPException(status_code=404, detail="Location not found")
return location
# 库存操作
@router.put("/inventory/")
def update_inventory(inventory: InventoryUpdate, db: Session = Depends(get_db)):
return crud_inventory.update_inventory(db, inventory_in=inventory)
```
#### 8. `main.py` - 应用入口
```python
from fastapi import FastAPI
from db import Base, engine
from api.api import router as api_router
# 创建数据库表(生产环境应使用迁移工具)
Base.metadata.create_all(bind=engine)
app = FastAPI(
title="仓库管理系统API",
description="仓库库存管理后端系统",
version="0.1.0"
)
app.include_router(api_router, prefix="/api")
@app.get("/")
def read_root():
return {"message": "仓库管理系统API服务运行中"}
```
#### 9. `requirements.txt` - 依赖清单
```
fastapi==0.85.0
uvicorn==0.19.0
sqlalchemy==1.4.41
pymysql==1.0.2
pydantic==1.10.2
python-dotenv==0.21.0
alembic==1.9.2
```
### 关键功能说明
1. **三层架构设计**:
- 模型层:定义数据库表结构
- CRUD层:封装数据库操作
- API层:处理HTTP请求和响应
2. **数据库操作**:
- 使用SQLAlchemy ORM进行数据库操作
- 依赖注入管理数据库会话
- 通用CRUD模式减少重复代码
3. **库存管理核心**:
- 产品管理(创建/查询)
- 仓库位置管理
- 库存更新(按位置分配库存)
4. **安全考虑**:
- 环境变量管理敏感配置
- JWT令牌支持(示例中预留接口)
### 使用说明
1. 创建虚拟环境并安装依赖:
```bash
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
```
2. 启动服务:
```bash
uvicorn main:app --reload
```
3. 访问API文档:
```
http://localhost:8000/docs
```
### 数据库迁移配置(附加说明)
1. 初始化Alembic:
```bash
alembic init db/migrations
```
2. 修改`alembic.ini`:
```ini
sqlalchemy.url = mysql+pymysql://user:password@localhost:3306/warehouse
```
3. 修改`db/migrations/env.py`:
```python
from models.models import Base # 添加导入
target_metadata = Base.metadata # 修改这行
```
4. 创建迁移脚本:
```bash
alembic revision --autogenerate -m "Initial migration"
```
5. 应用迁移:
```bash
alembic upgrade head
```
### 相关问题