zq-platform初始数据写不到数据库问题解决详细操作流程
我复现一下上面的操作说 zq-platform初始数据写不到数据库 第一次执行 报错 意思是:你的数据库当前版本 (current) 落后于 Alembic 迁移脚本所定义的最新版本 (head) cnblogs.com+1。这就好比你手里拿着的是第3版的说明书,但产品已经更新到第5版了 要解决这个问题,核心思路就是将数据库的当前版本 (current) 更新到与最新的迁移脚本版本 (head) 一致。 1.查看当前数据库状态:首先,确认一下版本差异。在项目根目录下打开终端,依次运行: 你通常会看到 current 的版本号比 heads 的版本号要旧,或者 heads 显示了多个分支(这通常意味着存在多个分支迁移需要合并)。 分别显示 这证实了问题所在:数据库当前停留在一个空版本,并没有处于最新状态,所以 Alembic 拒绝你生成新的迁移脚本。 请直接运行下面这条命令来解决这个问题: 这个命令会扫描 alembic/versions 文件夹,找到所有脚本,并依次在数据库中执行它们。 执行结果: 数据库已经成功升级到最新版本了。从输出 Running upgrade b6a31168d666 -> a79453452d83 可以看到:数据库已经更新到了 a79453452d83, 打开数据库可以看到当前版本号: 重新生成迁移:现在可以再次尝试运行 alembic revision --autogenerate -m “init tables”。 显示结果: 输出显示:Generating ... 588bd64ec92e\_init\_tables.py ... done 这表示 Alembic 成功扫描了你的代码和数据库,并发现它们之间的差异,自动生成了一个新的迁移脚本文件: 588bd64ec92e\_init\_tables.py。 接下来的步骤:让修改生效 现在脚本文件只是生成了,但数据库里的表结构还没变。你需要执行最后一步: 1. 查看生成的脚本(可选,但推荐) 你可以打开 alembic\versions\ 9abfcdbaff03\_init\_tables.py 看一眼。检查 upgrade() 函数里是否包含了 op.create\_table(…) 等语句。如果那里是空的,说明 Alembic 没检测到你的模型变化,或者模型没有被正确导入。 2. 更新数据库(必须执行) 在终端运行: 这将会把刚才生成的脚本应用到你的 fastapi\_db 数据库中,创建对应的表结构。 显示 数据库迁移已经完全成功了!🎉 从输出 Running upgrade a79453452d83 -> 588bd64ec92e 可以确认: 你的 fastapi\_db 数据库已经成功应用了 init tables 脚本,所有定义的表结构现在都已经真实存在于数据库中了。 验证成果 如果你想确认表真的创建好了,可以: 1.打开 pgAdmin(如果你安装了的话)。 2.连接到 fastapi\_db。 3.展开 Schemas -> public -> Tables。 4.你应该能看到刚才定义的所有数据表(比如 users 等)。 或者,你可以直接在 Python 代码中试着向数据库写入一条数据,看是否报错。 再执行python scripts/ loaddata.py db\_init.json,导入数据,看到 先不要激动!!!日志最后一句“导入完成: 成功 38 条 / 失败 0 条”是脚本自己打印的统计,并不真实—— 只要发生 ROLLBACK,整个事务就被回滚,数据库里一条新数据也没有写进去。 真正的失败原因就是这一条: 也就是 core\_user.last\_login 字段传的是 字符串,而数据库列类型是 timestamp without time zone,异步驱动 asyncpg 不接受字符串隐式转换。 如何修复 再执行python scripts/ loaddata.py db\_init.json,直至这些数据都导入完成。 当看到 ·脚本成功读取了 db\_init.json 文件,识别出包含 38 条待导入的记录 ·SQLAlchemy 引擎成功连接到 PostgreSQL 数据库(日志中出现 pg\_catalog.version() 是 PostgreSQL 特有的查询) 数据库验证 出现账号数据即为数据导入成功。 启动服务 这样初始数据写不到数据库问题就可以得到根本解决。alembic revision --autogenerate -m "init tables"INFO [
alembic.runtime.migration]
Context impl PostgresqlImpl.INFO [
alembic.runtime.migration]
Will assume transactional DDL.ERROR [
alembic.util.messaging]
Target database is not up to date.FAILED: Target database is not up to date. # 查看数据库当前记录的版本 alembic current # 查看所有可用的迁移脚本版本(head) alembic headsINFO [
alembic.runtime.migration]
Context impl PostgresqlImpl.INFO [
alembic.runtime.migration]
Will assume transactional DDL.alembic upgrade headINFO [
alembic.runtime.migration]
Context impl PostgresqlImpl.INFO [
alembic.runtime.migration]
Will assume transactional DDL.INFO [
alembic.runtime.migration]
Running upgrade -> b6a31168d666, init tablesINFO [
alembic.runtime.migration]
Running upgrade b6a31168d666 -> a79453452d83, add page design
alembic revision --autogenerate -m "init tables"INFO [
alembic.runtime.migration]
Context impl PostgresqlImpl.INFO [
alembic.runtime.migration]
Will assume transactional DDL.Generating F:\下载程序与源码\★★★可执行项目收集★★★\zq-platform\backend-fastapi\alembic\versions\588
bd64ec92e_init_tables.py
... donealembic upgrade headINFO [
alembic.runtime.migration]
Context impl PostgresqlImpl.INFO [
alembic.runtime.migration]
Will assume transactional DDL.INFO [
alembic.runtime.migration]
Running upgrade a79453452d83 -> 588bd64ec92e, init tables导入完成: 成功: 38 条 失败: 0 条
asyncpg.exceptions.DataError:
invalid input for query argument $4: '2026-01-11T19:44:39.752685' (expected a
datetime.date
or
datetime.datetime
instance, got 'str')def parse_datetime(value): """解析日期时间字符串""" if isinstance(value, str): # 尝试多种日期时间格式 formats = [ "%Y-%m-%dT%H:%M:%S.%f", # ISO 格式带微秒 "%Y-%m-%dT%H:%M:%S", # ISO 格式不带微秒 "%Y-%m-%d %H:%M:%S.%f", # 带微秒的空格分隔格式 "%Y-%m-%d %H:%M:%S", # 不带微秒的空格分隔格式 "%Y-%m-%d", # 仅日期格式 ] for fmt in formats: try: return
datetime.strptime(value,
fmt) except ValueError: continue # 如果以上格式都不匹配,尝试 fromisoformat try: return
datetime.fromisoformat(value.replace(
"Z", "+00:00")) except ValueError: pass # 如果所有尝试都失败,返回原始值 return value return value ...... # 转换日期时间字段 for key, value in
fields.items():
if isinstance(value, str): # 检查是否为日期时间格式的字符串 parsed_value = parse_datetime(value) # 如果成功解析且返回的是 datetime 对象,则替换原值 if isinstance(parsed_value, datetime): fields[key] = parsed_value从文件导入数据:
db_init.json
读取到 38 条记录2026-01-20 17:07:52,224 INFO
sqlalchemy.engine.Engine
select
pg_catalog.version()
2026-01-20 17:07:52,225 INFO
sqlalchemy.engine.Engine
[raw sql] ()......2026-01-20 17:07:52,276 INFO
sqlalchemy.engine.Engine
COMMIT导入完成: 成功: 38 条 失败: 0 条
python main.py或使用 uvicornuvicorn main:app --reload --host 0.0.0.0 --port 8000






