郑州网站建设知乎,网建网络科技有限公司,品牌网站设计打造,建设wap手机网站制作问题背景
使用fastapi-scaff脚手架创建项目后#xff0c;发现三个常见问题#xff1a;
时区配置缺失 默认的user导入的时区类有的python版本不支持 好像至于哦3.9才有 #xff1f;我是3.11也是报错的ORM Base类不一致 统一使用 DeclBase数据库迁移工具alembic 配置文件…问题背景使用fastapi-scaff脚手架创建项目后发现三个常见问题时区配置缺失 默认的user导入的时区类有的python版本不支持 好像至于哦3.9才有 我是3.11也是报错的ORM Base类不一致 统一使用 DeclBase数据库迁移工具alembic 配置文件完整解决方案第一步创建项目# 1. 安装脚手架pipinstallfastapi-scaff0.5.7# 2. 创建项目fastapi-scaff create my_fastapi --database sqlite# 3. 进入项目目录cdmy_fastapifastapi-scaff 常见参数 -h可以直接看-e, --editionnew时可指定项目结构版本(默认标准版)这个用的多一些 -d, --dbnew时可指定项目数据库(默认sqlite)-v, --vnadd时可指定版本(默认v1)-s, --subdiradd时可指定子目录(默认空)-t, --targetadd时可指定目标(默认asm)--celerynew|add时可指定是否集成celery(默认不集成)examples:new:fastapi-scaff newmyprojadd:fastapi-scaffaddmyapi第二步添加缺失依赖# 添加时区和迁移工具依赖echotzdata2021.5requirements.txtechoalembic1.11.0requirements.txt# 安装所有依赖pipinstall-r requirements.txt第三步创建时区工具文件# 创建统一时区工具catapp/utils/mytime.pyEOF from datetime import datetime from zoneinfo import ZoneInfo SHANGHAI_TZ ZoneInfo(Asia/Shanghai) def now() - datetime: 返回上海时区的当前时间 return datetime.now(SHANGHAI_TZ) def now_timestamp() - int: 返回当前时间戳秒 return int(now().timestamp()) def now_ms() - int: 返回当前时间戳毫秒 return int(now().timestamp() * 1000) EOF第四步修改用户模型# 备份原文件cpapp/models/user.py app/models/user.py.backup# 使用sed修改文件sed-i/from toollib.utils import now2timestamp/dapp/models/user.pysed-i/from app.initializer import g/a\from app.utils import mytimeapp/models/user.pysed-is/defaultnow2timestamp/defaultmytime.now_timestamp/gapp/models/user.py修改后的关键部分fromsqlalchemyimportColumn,BigInteger,Integer,Stringfromapp.initializerimportgfromapp.modelsimportDeclBasefromapp.utilsimportmytime# 新增导入classUser(DeclBase):__tablename__user# ... 其他字段保持不变created_atColumn(BigInteger,defaultmytime.now_timestamp,comment创建时间)updated_atColumn(BigInteger,defaultmytime.now_timestamp,onupdatemytime.now_timestamp,comment更新时间)第五步初始化Alembic迁移# 初始化Alembicalembic init alembic# 配置env.py使用项目Base类catalembic/env.pyEOF # 添加项目路径 import sys import os sys.path.append(os.path.dirname(os.path.dirname(__file__))) # 导入Base类 from app.models import DeclBase target_metadata DeclBase.metadata # 设置数据库URL根据配置文件 config.set_main_option(sqlalchemy.url, sqlite:///app_dev.sqlite) EOF使用sqlite的完整env.py配置文件fromlogging.configimportfileConfigfromsqlalchemyimportengine_from_configfromsqlalchemyimportpoolfromalembicimportcontextimportosimportsys configcontext.config# Set database URL directlyconfig.set_main_option(sqlalchemy.url,sqlite:///app_dev.sqlite)# Add project root to Python pathproject_rootos.path.dirname(os.path.dirname(__file__))sys.path.append(project_root)# Import Base classtry:fromapp.modelsimportDeclBase target_metadataDeclBase.metadataexceptImportError:try:fromapp.initializer._dbimportDeclBase target_metadataDeclBase.metadataexceptImportError:fromsqlalchemy.ext.declarativeimportdeclarative_base DeclBasedeclarative_base()target_metadataDeclBase.metadataifconfig.config_file_nameisnotNone:fileConfig(config.config_file_name)defrun_migrations_offline():urlconfig.get_main_option(sqlalchemy.url)context.configure(urlurl,target_metadatatarget_metadata,literal_bindsTrue,dialect_opts{paramstyle:named},)withcontext.begin_transaction():context.run_migrations()defrun_migrations_online():connectableengine_from_config(config.get_section(config.config_ini_section,{}),prefixsqlalchemy.,poolclasspool.NullPool,)withconnectable.connect()asconnection:context.configure(connectionconnection,target_metadatatarget_metadata)withcontext.begin_transaction():context.run_migrations()ifcontext.is_offline_mode():run_migrations_offline()else:run_migrations_online()第六步执行数据库迁移# 生成迁移文件alembic revision --autogenerate -minit# 应用迁移alembic upgradehead# 验证表结构sqlite3 app_dev.sqlite.tablesAPI测试流程1. 启动服务uvicorn app.main:app --host0.0.0.0 --port8000--reload2. 创建用户curl-X POSThttp://127.0.0.1:8000/api/v1/user\-HContent-Type: application/json\-d{ phone: 13634759152, password: passwd, name: admin, age: 0, gender: 1 }3. 登录获取Tokencurl-X POSThttp://127.0.0.1:8000/api/v1/user/login\-HContent-Type: application/json\-d{ phone: 13634759152, password: passwd }4. 使用Token查询用户# 使用上一步返回的tokenTOKENeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjIwMDA5MDc1NjI2MjY1ODg2NzIiLCJwaG9uZSI6IjEzNjM0NzU5MTUyIiwibmFtZSI6ImFkbWluIiwiYWdlIjowLCJnZW5kZXIiOjEsImV4cCI6MTc2ODQ4MTIyOX0.yS_pyuHfR0FuctSsb86zebYVlk8CFK2-ErsQMBvRqaAcurl-X GEThttp://127.0.0.1:8000/api/v1/user/2000907562626588672\-Haccept: application/json\-HAuthorization: Bearer$TOKEN5. 查询用户列表curl-X GEThttp://127.0.0.1:8000/api/v1/user?page1size10\-Haccept: application/json\-HAuthorization: Bearer$TOKEN验证命令# 验证时区配置python -cfrom app.utils.mytime import now_timestamp; print(当前时间戳:, now_timestamp())# 验证数据库迁移alembic current# 验证表结构sqlite3 app_dev.sqliteSELECT name FROM sqlite_master WHERE typetable;问题排查清单问题检查命令解决方案时区错误python -c from zoneinfo import ZoneInfo; print(ZoneInfo(Asia/Shanghai))pip install tzdataAlembic找不到Basegrep -r DeclBase app/修改env.py导入路径迁移文件不生成sqlite3 app_dev.sqlite .tables检查env.py中的target_metadataToken认证失败检查用户表的jwt_key字段确保jwt_key不为空总结fastapi-scaff脚手架创建的项目需要手动补充三个核心配置时区统一创建app/utils/mytime.py替换所有时间相关函数数据库迁移初始化Alembic配置正确的Base类和数据库连接模型一致确保所有模型继承同一个Base类完成上述配置后项目即可正常运行完整的JWT认证流程和数据库迁移功能。欢迎焦虑 沟通 有错误 指正留言~