zq-platform初始数据写不到数据库问题解决详细操作流程

0 阅读5分钟

我复现一下上面的操作说 zq-platform初始数据写不到数据库 第一次执行-

alembic revision --autogenerate -m "init tables"

报错

INFO  [[            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Context impl PostgresqlImpl.INFO  [[
            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Will assume transactional DDL.ERROR [[
            alembic.util.messaging]
          ](http://alembic.util.messaging]) Target database is not up to date.FAILED: Target database is not up to date.

意思是:你的数据库当前版本 (current) 落后于 Alembic 迁移脚本所定义的最新版本 (head) cnblogs.com+1。这就好比你手里拿着的是第3版的说明书,但产品已经更新到第5版了

要解决这个问题,核心思路就是将数据库的当前版本 (current) 更新到与最新的迁移脚本版本 (head) 一致。

1.查看当前数据库状态:首先,确认一下版本差异。在项目根目录下打开终端,依次运行:

    # 查看数据库当前记录的版本    alembic current    # 查看所有可用的迁移脚本版本(head)    alembic heads

你通常会看到 current 的版本号比 heads 的版本号要旧,或者 heads 显示了多个分支(这通常意味着存在多个分支迁移需要合并)。 分别显示

INFO  [[            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Context impl PostgresqlImpl.INFO  [[
            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Will assume transactional DDL.

这证实了问题所在:数据库当前停留在一个空版本,并没有处于最新状态,所以 Alembic 拒绝你生成新的迁移脚本。

请直接运行下面这条命令来解决这个问题:

alembic upgrade head

这个命令会扫描 alembic/versions 文件夹,找到所有脚本,并依次在数据库中执行它们。

执行结果:

INFO  [[            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Context impl PostgresqlImpl.INFO  [[
            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Will assume transactional DDL.INFO  [[
            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Running upgrade  -> b6a31168d666, init tablesINFO  [[
            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Running upgrade b6a31168d666 -> a79453452d83, add page design

数据库已经成功升级到最新版本了。从输出 Running upgrade b6a31168d666 -> a79453452d83 可以看到:数据库已经更新到了 a79453452d83,

打开数据库可以看到当前版本号:

重新生成迁移:现在可以再次尝试运行 alembic revision --autogenerate -m “init tables”。

alembic revision --autogenerate -m "init tables"

显示结果:

INFO  [[            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Context impl PostgresqlImpl.INFO  [[
            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Will assume transactional DDL.Generating F:\下载程序与源码\★★★可执行项目收集★★★\zq-platform\backend-fastapi\alembic\versions\588[
            bd64ec92e_init_tables.py
          ](http://bd64ec92e_init_tables.py) ...  done

输出显示:Generating ... 588bd64ec92e_init_tables.py ... done

这表示 Alembic 成功扫描了你的代码和数据库,并发现它们之间的差异,自动生成了一个新的迁移脚本文件: 588bd64ec92e_init_tables.py。 接下来的步骤:让修改生效 现在脚本文件只是生成了,但数据库里的表结构还没变。你需要执行最后一步:

  1. 查看生成的脚本(可选,但推荐) 你可以打开 alembic\versions[ 9abfcdbaff03_init_tables.py ](http://9abfcdbaff03_init_tables.py) 看一眼。检查 upgrade() 函数里是否包含了 op.create_table(…) 等语句。如果那里是空的,说明 Alembic 没检测到你的模型变化,或者模型没有被正确导入。
  2. 更新数据库(必须执行) 在终端运行:
alembic upgrade head

这将会把刚才生成的脚本应用到你的 fastapi_db 数据库中,创建对应的表结构。

显示

INFO  [[            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Context impl PostgresqlImpl.INFO  [[
            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Will assume transactional DDL.INFO  [[
            alembic.runtime.migration]
          ](http://alembic.runtime.migration]) Running upgrade a79453452d83 -> 588bd64ec92e, init tables

数据库迁移已经完全成功了!🎉

从输出 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 条

先不要激动!!!日志最后一句“导入完成: 成功 38 条 / 失败 0 条”是脚本自己打印的统计,并不真实——

只要发生 ROLLBACK,整个事务就被回滚,数据库里一条新数据也没有写进去。

真正的失败原因就是这一条:

[
            asyncpg.exceptions.DataError:
          ](http://asyncpg.exceptions.DataError:)  invalid input for query argument $4: '2026-01-11T19:44:39.752685'  (expected a [
            datetime.date
          ](http://datetime.date) or [
            datetime.datetime
          ](http://datetime.datetime) instance, got 'str')

也就是 core_user.last_login 字段传的是 字符串,而数据库列类型是 timestamp without time zone,异步驱动 asyncpg 不接受字符串隐式转换。

如何修复-

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,
          ](http://datetime.strptime(value,) fmt)            except ValueError:                continue                # 如果以上格式都不匹配,尝试 fromisoformat        try:            return [
            datetime.fromisoformat(value.replace(
          ](http://datetime.fromisoformat(value.replace()"Z", "+00:00"))        except ValueError:            pass                # 如果所有尝试都失败,返回原始值        return value    return value    ......    # 转换日期时间字段                for key, value in [
            fields.items():
          ](http://fields.items():)                    if isinstance(value, str):                        # 检查是否为日期时间格式的字符串                        parsed_value = parse_datetime(value)                        # 如果成功解析且返回的是 datetime 对象,则替换原值                        if isinstance(parsed_value, datetime):                            fields[key] = parsed_value

再执行python scripts/ loaddata.py db_init.json,直至这些数据都导入完成。

当看到-

从文件导入数据: [
            db_init.json
          ](http://db_init.json)读取到 38 条记录2026-01-20 17:07:52,224 INFO [
            sqlalchemy.engine.Engine
          ](http://sqlalchemy.engine.Engine) select [
            pg_catalog.version()
          ](http://pg_catalog.version())2026-01-20 17:07:52,225 INFO [
            sqlalchemy.engine.Engine
          ](http://sqlalchemy.engine.Engine) [raw sql] ()......2026-01-20 17:07:52,276 INFO [
            sqlalchemy.engine.Engine
          ](http://sqlalchemy.engine.Engine) COMMIT导入完成:  成功: 38 条  失败: 0

·脚本成功读取了 db_init.json 文件,识别出包含 38 条待导入的记录·SQLAlchemy 引擎成功连接到 PostgreSQL 数据库(日志中出现 pg_catalog.version() 是 PostgreSQL 特有的查询)数据库验证 出现账号数据即为数据导入成功。

启动服务-

python main.py或使用 uvicornuvicorn main:app --reload --host 0.0.0.0 --port 8000

这样初始数据写不到数据库问题就可以得到根本解决。