记一次:django models到sqlalchemy models重构

本文记录了一次将Django的models转换为SQLAlchemy models的过程,包括部署Django应用,初始化数据库设置,查看数据库映射,使用Navicat导出数据库结构,以及将数据库逆向工程转化为SQLAlchemy模型。

部署本地开发环境的django应用,初始化数据库设置

PythonWebDev\web_develop\network\networkconsole-master\networkconsole\conf.py

import os

DEBUG = True
ALLOWED_HOSTS = ['*']
DB_NAME = os.getenv("DB_NAME", "nms_console")
DB_USER = os.getenv("DB_USER", 'root')
DB_PASSWORD = os.getenv("DB_PASSWORD", '')
DB_HOST = os.getenv("DB_HOST", "localhost")
DB_PORT = int(os.getenv("DB_PORT", "3306"))
REDIS_HOST = os.getenv("REDIS_HOST", '127.0.0.1')
REDIS_PORT = int(os.getenv("REDIS_PORT", '6379'))
LDAP_SERVER_URI = os.getenv("LDAP_SERVER_URI", 'ldap://10.222.10.244:389')
LDAP_PASSWORD = os.getenv("LDAP_PASSWORD", 'OUm6Wau+VuBX')
LOCK_FILE_PATH = '/ikglobal/lock/'
MESSAGE_PATH = '/ikglobal/logs/message.log'
LOG_REQUEST_ERROR_PATH = '/ikglobal/logs/request_error.log'
LOG_SQL_PATH = '/ikglobal/logs/sql.log'

将jango的sql mode映射到数据库

python manage.py migrate

查看生成的对应数据库和表

映射sql到sqlalchemy models

(vpp_agent_venv3.7) [root@localhost model]# pip install sqlacodegen
(vpp_agent_venv3.7) [root@localhost model]# sqlacodegen --outfile=nms_routein.py mysql+pymysql://root:123456@127.0.0.1:3306/nms_console
(vpp_agent_venv3.7) [root@localhost model]# ls
base_model.py  models2.py  models_mongo.py  models.py  nms_routein.py  __pycache__  route_in.py

通过navicat导出数据库结构

点击nms_console,右键选择转存sql文件数据和结构

/*
 Navicat Premium Data Transfer

 Source Server         : 127.0.0.1
 Source Server Type    : MySQL
 Source Server Version : 50721
 Source Host           : 127.0.0.1:3306
 Source Schema         : nms_console

 Target Server Type    : MySQL
 Target Server Version : 50721
 File Encoding         : 65001

 Date: 11/09/2019 20:25:28
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for common_config
-- ----------------------------
DROP TABLE IF EXISTS `common_config`;
CREATE TABLE `common_config`  (
  `uuid` char(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `data` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `room_id` char(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`uuid`) USING BTREE,
  UNIQUE INDEX `common_config_name_room_id_50e7a3f4_uniq`(`name`, `room_id`) USING BTREE,
  INDEX `common_config_room_id_1687cb8f_fk_common_room_uuid`(`room_id`) USING BTREE,
  CONSTRAINT `common_config_room_id_1687cb8f_fk_common_room_uuid` FOREIGN KEY (`room_id`) REFERENCES `common_room` (`uuid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for common_local_config
-- ----------------------------
DROP TABLE IF EXISTS `common_local_config`;
CREATE TABLE `common_local_config`  (
  `uuid` char(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `data` longtext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `room_id` char(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  PRIMARY KEY (`uuid`) USING BTREE,
  UNIQUE INDEX `common_local_config_name_room_id_2352bdaa_uniq`(`name`, `room_id`) USING BTREE,
  INDEX `common_local_config_room_id_177281a0_fk_common_room_uuid`(`room_id`) USING BTREE,
  CONSTRAINT `common_local_config_room_id_177281a0_fk_common_room_uuid` FOREIGN KEY (`room_id`) REFERENCES `common_room` (`uuid`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for co
<think> 嗯,用户想将Django项目迁移到FastAPI,这需要系统规划。根据引用内容有几个关键点:Django和FastAPI可以共存(引用[1]),但迁移涉及架构转换;考虑过Django Ninja这类过渡方案(引用[3]);两者在ORM、异步处理等方面差异较大(引用[4])。 用户可能面临的实际痛点是:想保留Django的数据层但利用FastAPI的高性能,或是需要渐进式迁移。需要重点解决几个矛盾:Django的全功能特性(如ORM、Admin)在FastAPI中如何替代;同步逻辑转异步的注意事项;路由和中间件的适配成本。 迁移路径应该分阶段:先用Django Ninja实现部分API(引用[3]示例),再逐步用FastAPI替换视图层,最后完全分离。特别要注意数据验证的转换——Django表单到Pydantic模型(引用[4]对比表),以及Worker从WSGI转ASGI的部署调整。 需要预警用户的坑:Django模板系统在FastAPI中不可用,内置权限体系要重写,还有信号(signals)机制的替代方案。最后补充冷迁移和增量迁移的选择建议,毕竟直接重写风险太高。 </think> 将 Django 项目迁移到 FastAPI 是一项系统工程,需要分步进行。以下是关键步骤和策略,结合引用信息和最佳实践: --- ### **1. 评估与规划** - **梳理现有功能**:明确需迁移的模型、视图、路由、中间件和认证模块(如 Django REST framework 的序列化器)。 - **选择迁移策略**: - **增量迁移**(推荐):在 Django 项目中逐步引入 FastAPI,并行运行(引用[1])。 ```python # Django urls.py 中挂载 FastAPI 应用 from fastapi import FastAPI fastapi_app = FastAPI() django_urlpatterns = [path("fastapi/", fastapi_app)] ``` - **完全重写**:适合中小型项目,但需重构数据层和业务逻辑。 --- ### **2. 数据层迁移** - **方案 A:保留 Django ORM** 沿用 Django 模型和数据库连接(需在 FastAPI 中初始化 Django): ```python # FastAPI 主文件中初始化 Django import os, django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings") django.setup() from myapp.models import MyModel # 直接导入 Django 模型 ``` - **方案 B:切换至 SQLAlchemy(异步推荐)** 使用 `databases` 或 `SQLModel` 替代 ORM: ```python # FastAPI 中使用 SQLAlchemy 示例 from sqlalchemy.ext.asyncio import AsyncSession @app.get("/items") async def read_items(db: AsyncSession = Depends(get_db)): result = await db.execute(select(MyModel)) return result.scalars().all() ``` --- ### **3. API 层重构** - **路由转换**: 将 Django 视图函数转为 FastAPI 路径操作: ```python # Django REST framework 视图 → FastAPI # Django: class UserViewSet(ModelViewSet) # FastAPI: @app.get("/users/{id}", response_model=UserSchema) async def get_user(id: int, db: Session = Depends(get_db)): return db.query(User).filter(User.id == id).first() ``` - **序列化替代**: 用 Pydantic 模型替换 DRF 序列化器(引用[4]): ```python from pydantic import BaseModel class UserCreate(BaseModel): name: str email: str = Field(..., regex=r"^[^@]+@[^@]+\.[^@]+$") ``` --- ### **4. 异步化改造(关键难点)** - **识别阻塞操作**:数据库查询、外部 API 调用等改为异步: ```python # 同步 Django 代码 → 异步 FastAPI # Django: def fetch_data(): requests.get(url).json() # FastAPI: async def fetch_data(): async with httpx.AsyncClient() as client: return (await client.get(url)).json() ``` - **Worker 调整**:部署时需使用 ASGI 服务器(如 Uvicorn)替代 WSGI(如 Gunicorn)。 --- ### **5. 集成共享组件** | **Django 组件** | **FastAPI 替代方案** | |--------------------|-----------------------------------| | 认证(Session/Auth) | JWT/OAuth2(`fastapi.security`) | | 中间件 | FastAPI 中间件或 Starlette 中间件 | | 定时任务(Celery) | 沿用或改用 `ARQ`(异步任务队列) | | Admin 后台 | 单独保留或改用 SQLAlchemy Admin | --- ### **6. 验证与优化** 1. **自动化测试**:用 `pytest` 覆盖迁移后的接口(FastAPI 内置 TestClient)。 2. **性能基准测试**:对比迁移前后的 QPS 和延迟(FastAPI 性能优势通常在 I/O 密集型场景)。 3. **监控**:集成 Prometheus 或 Sentry 跟踪错误和性能指标。 --- ### **替代方案:Django Ninja(渐进式迁移)** 若需最小成本迁移,可使用 **Django Ninja**(引用[3])在 Django 内构建 FastAPI 风格 API: ```python # 在现有 Django 项目中直接使用 from django_ninja import NinjaAPI api = NinjaAPI() @api.get("/users/{id}") def get_user(request, id: int): return User.objects.get(id=id) # 同步代码兼容 ``` > ✅ **优势**:无需重构数据层,支持渐进过渡到异步。 --- ### **迁移决策树** ```mermaid graph TD A[项目规模] -->|大型/复杂| B[增量迁移:Django+FastAPI 并行] A -->|中小型| C{需异步?} C -->|是| D[完全迁移至 FastAPI] C -->|否| E[使用 Django Ninja] ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值