Skip to content
Merged

Milvus #7445

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 5.2.16 on 2026-08-25 05:13

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("application", "0014_applicationversion_knowledge_ids"),
]

operations = [
migrations.AddField(
model_name="application",
name="default_model_setting",
field=models.JSONField(default=dict, verbose_name="默认模型设置"),
),
migrations.AddField(
model_name="applicationversion",
name="default_model_setting",
field=models.JSONField(default=dict, verbose_name="默认模型设置"),
),
]
23 changes: 0 additions & 23 deletions apps/application/migrations/0015_chat_execute_type.py

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,20 +1,67 @@
# Generated by Django 6.1 on 2026-09-09 09:28
# Generated by Django 6.1.2 on 2026-10-23 09:12

import common.encoder.encoder
import django.contrib.postgres.fields
from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("application", "0017_application_is_portal_and_more"),
("application", "0015_application_default_model_setting_and_more"),
]

operations = [
migrations.AddField(
model_name="chat",
name="execute_type",
field=models.CharField(
choices=[
("ANONYMOUS_USER", "匿名用户"),
("CHAT_USER", "对话用户"),
("SYSTEM_API_KEY", "系统API_KEY"),
("APPLICATION_API_KEY", "应用API_KEY"),
("PLATFORM_USER", "平台用户"),
],
default="CHAT",
max_length=64,
verbose_name="执行类型",
),
),
migrations.AddField(
model_name="chatrecord",
name="workflow_context",
field=models.JSONField(blank=True, default=dict, null=True, verbose_name="工作流上下文"),
),
migrations.AddField(
model_name="chatrecord",
name="messages",
field=django.contrib.postgres.fields.ArrayField(
base_field=models.JSONField(), default=list, verbose_name="响应message"
),
),
migrations.AddField(
model_name="chatrecord",
name="question",
field=models.JSONField(
default=dict, encoder=common.encoder.encoder.SystemEncoder, verbose_name="用户的消息"
),
),
migrations.AddField(
model_name="chatrecord",
name="version",
field=models.IntegerField(default=1, verbose_name="版本号"),
),
migrations.AddField(
model_name="application",
name="is_portal",
field=models.BooleanField(default=False, verbose_name="是否在门户上架"),
),
migrations.AlterField(
model_name="application",
name="default_model_setting",
field=models.JSONField(default=dict, verbose_name="默认模型"),
),
migrations.AddField(
migrations.AlterField(
model_name="applicationversion",
name="default_model_setting",
field=models.JSONField(default=dict, verbose_name="默认模型"),
Expand Down Expand Up @@ -70,4 +117,9 @@ class Migration(migrations.Migration):
verbose_name="执行类型",
),
),
migrations.AddField(
model_name="applicationversion",
name="publish_desc",
field=models.CharField(default="", max_length=1024, verbose_name="更新说明"),
),
]
17 changes: 0 additions & 17 deletions apps/application/migrations/0017_application_is_portal_and_more.py

This file was deleted.

This file was deleted.

9 changes: 8 additions & 1 deletion apps/common/config/embedding_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,12 @@ def delete_key(_id):

class VectorStore:
from knowledge.vector.pg_vector import PGVector
from knowledge.vector.milvus_vector import MilvusVector
from knowledge.vector.base_vector import BaseVectorStore

instance_map = {
"pg_vector": PGVector,
"milvus": MilvusVector,
}
instance = None

Expand All @@ -104,6 +106,11 @@ def get_embedding_vector() -> BaseVectorStore:
if VectorStore.instance is None:
from maxkb.const import CONFIG

vector_store_class = VectorStore.instance_map.get(CONFIG.get("VECTOR_STORE_NAME"), PGVector)
# VECTOR_STORE_NAME 显式指定优先;未指定时按 MILVUS_URI 有无自动判断
# (配了 MILVUS_URI 用 milvus,否则 pg_vector,保证老用户零改动)
name = CONFIG.get("VECTOR_STORE_NAME")
if not name:
name = "milvus" if CONFIG.get("MILVUS_URI") else "pg_vector"
vector_store_class = VectorStore.instance_map.get(name, PGVector)
VectorStore.instance = vector_store_class()
return VectorStore.instance
50 changes: 50 additions & 0 deletions apps/common/db/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# v2 → v3 数据库升级

v3 增量迁移按 Django app 合并,统一执行 `python apps/manage.py migrate`。
原先有多个增量文件的 app 仅保留以下升级入口,18 个原 v3 增量文件已删除;
完整保留 v2 的迁移链:

| app | v3 入口 |
| --- | --- |
| application | `0016_v3_upgrade` |
| knowledge | `0012_v3_upgrade` |
| users | `0002_v3_upgrade` |
| system_manage | `0006_v3_upgrade` |

`models_provider/0002_rename_wenxin_provider_to_qianfan`、
`tools/0009_toolworkflowversion_publish_desc` 和 `portal/0001_initial`
本身各只有一个 v3 迁移,直接保留。

合并文件只负责从 v2 升级,按顺序执行普通 Django 迁移操作。
不识别开发期间旧 v3 增量迁移的执行记录,也不支持续跑部分升级的开发数据库。
以下 v2 原始迁移按原文件名、原内容保留在各 app 的 `migrations/` 目录:

- `knowledge.0010_publicfileaccess`:`public_file_access` 表。
- `knowledge.0011_knowledgeworkflow_default_model_setting_and_more`:知识库工作流及版本的默认模型配置。
- `application.0015_application_default_model_setting_and_more`:应用及版本的默认模型配置。

知识库在 v2 的 `0011` 后执行 `0012_v3_upgrade`;
应用在 v2 的 `0015` 后执行 `0016_v3_upgrade`。

已有 v2 数据库由 Django 根据原迁移记录自然跳过已执行的操作;较早 v2 先补齐剩余 v2
迁移,再执行 v3 增量。无需自定义迁移兼容类、手动改写记录或 `--fake`。
v3 不再重复创建 `public_file_access` 和 `default_model_setting`;后者仅同步字段显示名称。
新迁移失败时,当前 app 的变更随事务回滚,可修复原因后重新执行 `migrate`。

升级前备份数据库和文件存储,并先在数据库副本上执行迁移、知识库检索和对话验证。
此迁移处理数据库结构;不将 PG 向量自动搬到 Milvus,也不转换旧工作流的执行逻辑。

## 回归验证

```bash
python apps/manage.py test common.tests.test_v2_migrations
```

迁移回归需要独立的 PostgreSQL 测试实例、创建测试库权限和 `vector` 扩展。
将 `MAXKB_DB_*` 全部指向该测试实例后运行:旧的 `0002_refresh_collation_reindex`
会额外访问配置中的 `DB_NAME` 和 `root` 库,因此不能使用业务库配置执行迁移测试。
回归用例在 Django 创建的测试库中回退并重建迁移状态。
上述三个 v2 原始迁移来自 `origin/v2` 提交 `792a525c5`,应保持原样。
测试直接用 Django 迁移执行器迁移至 v2 的真实依赖节点,写入历史数据后升级至 v3,
验证 v2 基础版本及较新版本升级、公共文件授权、默认模型配置、对话、向量和 Token 数据保留,
以及重复运行不产生额外迁移。
Loading
Loading