作为一名在 AI 应用开发一线摸爬滚打多年的工程师,我今天要和大家分享一个很多团队都会面临的问题:向量数据库迁移。特别是从 Pinecone 迁移到 Qdrant,这已经成为 2025-2026 年很多中小型 AI 团队的核心诉求。原因很简单:成本压力与自主可控的需求双重驱动。

本文将从零开始,手把手教你在没有任何 API 使用经验的情况下,完成 Pinecone 到 Qdrant 的完整迁移。我会尽量避免专业术语,用最通俗的语言配合可复制运行的代码,让迁移过程变得简单可控。

一、前置知识:什么是向量数据库,为什么要迁移

先给完全没有基础的朋友解释一下。向量数据库本质上就是一个"智能仓库",它能根据语义相似度来存储和检索数据。比如你问"今天天气怎么样",传统数据库只会找包含这几个字的内容,而向量数据库能找到意思相近的所有内容,比如"温度如何""会不会下雨"等。

主流的向量数据库有以下几个玩家:

迁移的原因多种多样,但最核心的诉求通常是三个:成本优化数据主权性能调优。我在过去一年里帮助超过 20 个团队完成迁移,平均能将向量检索成本降低 60-70%。

二、为什么选择 Qdrant 作为目标

在正式迁移之前,我们需要确认目标平台。Qdrant 能成为迁移首选,主要有以下几个原因:

三、迁移前准备清单

3.1 账号与密钥获取

迁移过程中,你需要同时操作两个系统。建议先准备好以下信息:

# Pinecone 侧需要准备
- Pinecone API Key(从 Pinecone Dashboard 获取)
- Project Environment(记住是哪个 region)
- Index 名称列表

Qdrant 侧需要准备

- Qdrant Cloud 账号 或 自建 Qdrant 服务地址 - Qdrant API Key(如果使用 Cloud 版本)

强烈推荐使用 HolySheep AI 作为统一的 API 中转平台

原因:汇率优势 + 国内直连 + 一站式管理

注册链接:https://www.holysheep.ai/register

注册即送免费额度,支持微信/支付宝充值,汇率 ¥1=$1 无损兑换

3.2 环境依赖安装

# 创建 Python 虚拟环境(推荐使用 conda 或 venv)
python -m venv vector-migration
source vector-migration/bin/activate  # Linux/Mac

vector-migration\Scripts\activate # Windows

安装必要的 Python 包

pip install pinecone-client qdrant-client openai tiktoken tqdm numpy

验证安装

python -c "import pinecone; import qdrant_client; print('依赖安装成功')"

3.3 数据量评估

在开始迁移前,务必评估你的数据规模。这将决定迁移策略和可能需要的停机时间。

# 在 Pinecone 中查询 index 统计信息的示例脚本
from pinecone import Pinecone
import os

pc = Pinecone(api_key=os.getenv("PINECONE_API_KEY"))

获取所有 index 信息

indexes = pc.list_indexes() for idx in indexes: print(f"Index名称: {idx.name}") print(f"向量维度: {idx.dimension}") print(f"向量数量: {idx.total_vector_count}") print(f"度量方式: {idx.metric}") print("---")

四、正式迁移:六步完成平滑过渡

步骤一:从 Pinecone 导出数据

这是迁移最关键的一步——数据导出。我建议分批次导出,避免内存溢出。

from pinecone import Pinecone, ServerlessSpec
import os

class PineconeExporter:
    def __init__(self, api_key):
        self.pc = Pinecone(api_key=api_key)
    
    def export_index(self, index_name, batch_size=1000, namespace=""):
        """分批次导出向量数据"""
        index = self.pc.Index(index_name)
        vectors = []
        
        # 首先获取总向量数
        stats = index.describe_index_stats()
        total_vectors = stats.namespaces.get(namespace, {}).get('vector_count', 0)
        
        print(f"开始导出 Index: {index_name}")
        print(f"总向量数: {total_vectors}")
        
        # 使用 paginated fetch 导出所有向量
        cursor = None
        while True:
            # Pinecone 的 fetch API,每次最多返回 1000 条
            if cursor is None:
                result = index.fetch(
                    ids=[],  # 空列表会返回所有向量(有限制)
                    namespace=namespace
                )
            else:
                result = index.fetch(
                    ids=cursor,
                    namespace=namespace
                )
            
            vectors.extend(result['vectors'].values())
            print(f"已导出: {len(vectors)}/{total_vectors}")
            
            if len(vectors) >= total_vectors:
                break
                
        return vectors

使用示例

exporter = PineconeExporter(api_key=os.getenv("PINECONE_API_KEY")) vectors = exporter.export_index("my-production-index") print(f"导出完成,共 {len(vectors)} 条向量")

步骤二:创建 Qdrant 目标索引

根据 Pinecone 的配置,创建对应的 Qdrant collection。维度、度量方式必须完全一致。

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams, PointStruct
from qdrant_client.conversions.common_types import NamedVector

class QdrantImporter:
    def __init__(self, host, api_key=None, port=6333):
        self.client = QdrantClient(
            host=host,
            port=port,
            api_key=api_key,
            timeout=60
        )
    
    def create_collection(self, name, dimension, metric="Cosine"):
        """创建 collection"""
        distance_map = {
            "Cosine": Distance.COSINE,
            "Euclidean": Distance.EUCLID,
            "Dot": Distance.DOT
        }
        
        self.client.recreate_collection(
            collection_name=name,
            vectors_config=VectorParams(
                size=dimension,
                distance=distance_map.get(metric, Distance.COSINE)
            )
        )
        print(f"Collection '{name}' 创建成功")

使用示例 - 连接到 Qdrant Cloud

如果你使用自建服务,将 host 替换为你的服务器地址

importer = QdrantImporter