dify 默认的数据库表,不一定是自己想要的。这个时候就需要取修改数据库表。修改数据库表最爽的方式就是用迁移文件。在 dify 原本的迁移目录下新增迁移文件会出现迁移版本错位的问题。比如你当前建立了一个迁移文件,过段时间拉 dify 官网代码合并后,迁移有改动,这个时候就会出现迁移版本对不上。为了解决这个问题,自定义个人迁移目录,新建迁移文件就很有必要了。
现在想给 api_tokens 表新增一个 account_id 字段。因为之前的 api_tokens 表只和 tenant 表进行关联,满足不了需求。
新建自定义迁移文件夹【该思路放弃】
修改 docker-compose.yaml 的 api 的配置。主要修改 volumes,因为默认是没有挂载目录,就会出现在容器中生成的文件在宿主机上没有。
api:
volumes:
- ../api:/app/api
# 匿名卷:让 .venv 目录不被宿主机覆盖,保留镜像内的内容
- /app/api/.venv
然后启动服务,开始干活。(从尝试到放弃)
# 启动 docker 服务
docker compose up -d
# 进入 api 容器
docker exec -it docker-api-1 bash
# 创建自定义迁移目录
flask db init --directory migrations_custom
# 查看官方迁移当前版本
flask db current
# 给自定义迁移库打基线(7bad07dc267d 是上一步查询出来的)
flask db stamp --directory migrations_custom 7bad07dc267d --purge
从尝试到放弃
想法是很美好,可是执行起来,各种问题就来了。所以,还是放弃自建迁移文件的想法了。既然迁移文件不好使,那就调用 sql 来达到实现修改字段的目的了。
在 api/extensions 目录下,新建 ext_database_custom.py 文件。代码入下。
# ext_database_custom.py
from sqlalchemy import text as sql_text
from extensions.ext_database import db
from dify_app import DifyApp
def init_custom_db_fields():
"""初始化自定义数据库字段/索引,启动自动执行"""
try:
with db.engine.connect() as conn:
# 新增 account_id 字段
conn.execute(
sql_text(
"ALTER TABLE api_tokens ADD COLUMN IF NOT EXISTS account_id UUID;"
)
)
# 新增联合索引
conn.execute(
sql_text(
"CREATE INDEX IF NOT EXISTS api_token_account_idx ON api_tokens(account_id, type);"
)
)
conn.commit()
print("[CustomDB] 自定义字段&索引初始化完成")
except Exception as e:
print(f"[CustomDB] 初始化异常: {str(e)}")
# 关键:实现 Dify 扩展标准接口 init_app
def init_app(app: DifyApp):
# 这里要在 app 上下文里执行,否则 db 可能没绑定
with app.app_context():
init_custom_db_fields()
然后在 api/app_factory.py 的 initialize_extensions 函数中,引入注册插件。放在 ext_database 后边即可。
最后执行 docker compose restart 就可以了。
