mcpField
S
setting-up-a-data-warehouse-source

setting-up-a-data-warehouse-source

github.com/posthog数据与数据库76377 次安装今天更新
代码仓库

关于 setting-up-a-data-warehouse-source

这项 PostHog 技能指导将外部数据源接入数据仓库,涵盖安全收集凭据和单步设置,也提供手动选择表与同步方式的流程。

主要功能

  1. 01通过安全浏览器链接交接凭据
  2. 02单次调用创建数据源
  3. 03发现数据表并应用同步默认值
  4. 04手动选择数据表和同步方式
  5. 05Webhook 与 CDC 配置指引

适用场景

  1. 01接入新的 Stripe 或 Postgres 数据源
  2. 02选择要同步的数据表
  3. 03为数据表设置非默认同步方式
  4. 04注册 Webhook 或配置 Postgres CDC

MCP 相关

该技能指导使用 PostHog MCP 工具发现、验证和创建数据仓库数据源,并配置数据表、Webhook 和 CDC。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/posthog/skills --skill setting-up-a-data-warehouse-source

安装后在 Claude Code 中输入/setting-up-a-data-warehouse-source确认已加载。

附带文件references/sync-types.md

详细介绍

设置数据仓库数据源

当用户想首次将外部数据源连接到 PostHog 数据仓库时,使用此技能。

默认使用一步式流程: data-warehouse-source-setup 会验证凭据、发现所有表、使用合理的同步默认设置(尽可能采用增量同步)启用这些表,并在一次调用中创建数据源,无需组装 schemas 数组。对于凭据,使用 data-warehouse-source-connect-link 为用户提供安全的浏览器链接,而不是在聊天中收集机密信息。只有当用户想手动挑选要同步的表,或为每张表设置非默认同步类型时,才使用手动的 wizard → db-schema → create 流程。

何时使用此技能

  • 用户想连接新的数据源:“连接 Stripe”“导入我的 Postgres 订单表”“同步 Hubspot 联系人”
  • 用户不确定 PostHog 支持哪些数据源类型
  • 用户有凭据,但不知道如何构造 schemas 载荷
  • 用户想了解每张表应选择哪种同步方式

可用工具

工具用途
data-warehouse-source-connect-link凭据首选方式 — 获取安全的浏览器/OAuth 链接,让用户完成身份验证,而无需在聊天中粘贴机密信息
data-warehouse-source-setup创建首选方式 — 一次调用即可验证凭据、发现表、应用同步默认设置并创建数据源
external-data-sources-wizard发现现有的数据源类型及各类型所需的字段(高级流程)
external-data-sources-db-schema验证凭据并列出各表可用的同步方式(高级流程)
external-data-sources-create高级创建方式 — 需要根据 db-schema 响应构建 schemas 数组
external-data-sources-check-cdc-prerequisites-createPostgres CDC 预检(可选,仅用于 Postgres CDC)
external-data-sources-webhook-info-retrieve检查数据源是否支持 Webhook,以及是否已注册 Webhook
external-data-sources-create-webhook-create创建数据源后,向外部服务注册 Webhook
external-data-sources-update-webhook-inputs-create自动注册失败时,手动提供签名密钥
external-data-sources-list创建后,确认数据源已列出并查看其初始状态
external-data-schemas-list创建数据源后,查看各表的同步状态

准备工作:导致大多数失败的凭据注意事项

收集凭据之前,请先说明这些注意事项——它们是首次设置失败的主要原因。提前检查这些问题,可以避免重试时反复提示用户输入凭据。

  • PostHog 的网络必须能够访问该主机。 localhost、127.0.0.1 和私有/RFC-1918 主机(10.x、192.168.x、172.16–31.x)都会被拒绝——PostHog 会从自己的基础设施发起连接,而不是从用户的机器发起。无服务器/托管式 Postgres(Neon、Supabase、受严格规则限制的 RDS)通常也需要先将 PostHog 的出口 IP 加入允许列表。如果数据库无法通过公网访问,请改用浏览器深层链接(data-warehouse-source-connect-link)或 SSH 隧道,而不要收集无法通过验证的凭据。
  • Supabase 就是 Postgres——不要重复收集。 使用 Session pooler 连接,而不要使用直连主机(直连主机仅支持 IPv6)。连接池主机格式类似 aws-0-<region>.pooler.supabase.com,用户名必须是 postgres.<project-ref>,端口为 6543(而不是 5432)。密码是数据库密码(Settings → Database),与 anon/service_role JWT 密钥以及 Supabase 账户密码不同。如果项目环境中有 SUPABASE_URL,请从 db.<ref>.supabase.co 提取项目 ref 并预先填入这些信息,而不要让用户猜测。
  • 许多 SaaS 数据源需要特定类型的密钥或套餐——请在创建调用失败之前获取正确的信息:
    • Stripe — 使用 restricted 密钥(rk_live_…),而不是标准的 secret 密钥(sk_live_…)。
    • RevenueCat — 使用启用了读取权限范围的 v2 secret 密钥(sk_…)。
    • Sentry — 使用内部集成令牌,而不是 DSN 或个人身份验证令牌。
    • Convex — 需要 Professional 套餐。
    • Twilio — 使用 API Key SID + Secret,而不是账户身份验证令牌。
    • Mailchimp — 密钥包含数据中心后缀(key-usX)。
    • 对于仅发送服务(Resend、Mailgun),项目环境中已有的密钥通常受限;数据仓库导入需要具有完整/读取访问权限的密钥。
  • 绝不要传递尚未解析的密钥引用。 如果凭据字段仍是 {"secretRef": ...} 对象,PostHog 就无法解析它——create/db-schema/setup 调用会报出明确错误并拒绝请求。请先将其解析为实际值,或者通过 data-warehouse-source-connect-link 收集凭据,并传递得到的 credential_id。

推荐:一步完成设置

大多数设置都应使用此路径 — 它可以避免最常见的失败情况(跳过 db-schema、schemas 格式错误、缺少必填字段)。

  1. 发现数据源类型及其字段(可选):external-data-sources-wizard 会列出所有数据源类型及其所需的凭据字段。用它来了解需要向用户询问哪些信息;如果数据源类型显而易见,则跳过此步骤。

  2. 安全收集凭据:调用 data-warehouse-source-connect-link({source_type})。它会返回一个 connect_url,指向一个精简的连接页面,该页面会显示数据源的完整连接表单 — 用户可通过 OAuth 授权,或在页面中输入凭据,具体取决于数据源提供的方式(响应中的 auth_method 会告知你预期的方式)。页面会通过实时连接验证信息,并将其加密后存入临时存储 — 它不会创建数据源。用户确认完成后,通过 data-warehouse-stored-credentials-list 查找已存储凭据的 ID(按 source_type 筛选,最新的排在最前;页面也会向用户显示该 ID),并将 {"credential_id": <id>} 传给设置流程。已存储的凭据只能使用一次 — 设置流程使用后会立即删除 — 并会在 24 小时后过期。

    切勿要求用户在聊天中粘贴原始数据库密码、API 密钥或 OAuth 令牌。

  3. 一次调用即可创建:data-warehouse-source-setup({source_type, payload, prefix})。服务会验证凭据、发现所有表、按同步默认值启用这些表(存在跟踪列时使用增量同步,否则使用追加同步,再否则使用 full_refresh — 绝不使用 CDC)、设置 created_via=mcp,并创建数据源。payload 中包含凭据引用({"credential_id": ...} 或 OAuth 集成 ID 键)— 也可以用于无头自动化的内联凭据;不需要 schemas 数组。成功后会返回新数据源的 id;调用 external-data-schemas-list,向用户展示已启用的表及各表的同步方式。

此路径的注意事项:

  • **所有发现的表都会启用。**这是有意为之(增量默认设置可降低持续成本),但对于非常大的表,应提示其行数,并在用户只想同步部分表时提供高级流程。
  • 支持 Webhook 的数据源会自动注册 Webhook(目前为 Stripe)。检查设置响应中的 webhook 键:成功时,支持 Webhook 的表会实时同步,仅支持 Webhook 的表(例如 Stripe Discount)也会启用;失败时(例如 API 密钥无法创建 Webhook),表会保留轮询默认设置,仅支持 Webhook 的表会保持禁用 — 向用户转达 webhook.error,并提供第 6 步以手动注册。如果 webhook.pending_inputs 非空,请收集这些值并通过 external-data-sources-update-webhook-inputs-create 提交。不会自动选择 CDC;对于近实时 Postgres,请使用高级流程和 CDC 步骤。
  • payload 中仍可使用内联凭据进行无头操作或自动化,但优先使用上述连接链接交接方式。

高级:手动选择表(三步流程)

当用户想精确选择要同步的表,或设置非默认同步类型时,请使用此流程。不要尝试跳过步骤,直接调用 external-data-sources-create — 你需要 db-schema 响应才能构建有效的 schemas 载荷。

         ┌────────────────────┐
         │ 1. wizard          │  What source types exist? What fields does each need?
         └────────┬───────────┘
                  ▼
         ┌────────────────────┐
         │ 2. db-schema       │  Validate creds. List tables + available sync methods per table.
         └────────┬───────────┘
                  ▼
         ┌────────────────────┐
         │ 3. create          │  Send source_type + credentials + schemas[] to actually create.
         └────────────────────┘

工作流

步骤 1 — 发现源类型

调用 external-data-sources-wizard,并将 source_type 设为你需要的类型(用逗号分隔,例如 Postgres,Stripe)。未筛选的响应会描述所有受支持的源,大小达数百 KB,足以耗尽上下文预算。只有在确实需要枚举所有可用类型时才省略 source_type;此时请传入 fields: ['*.name', '*.caption'],这样响应只包含名称,而不是每个源的所有配置字段定义。响应是一个以源类型为键的字典。每个条目描述:

  • name — 规范的 source_type 字符串,供后续调用传入(例如 "Postgres"、"Stripe"、"Hubspot")。
  • caption — 面向用户的描述。
  • fields — 所需的配置字段(host、port、database、api_key、client_id/secret 等)。每个字段都有 name、 type(input、password、switch、select、file-upload)和 required。
  • featured、unreleasedSource — 用于判断就绪情况。跳过标记为 unreleasedSource: true 的源,除非用户明确要求预览版。

根据用户的请求匹配源。如果他们说“Postgres”,就查找 Postgres。如果他们说的内容含糊,例如“数据库”,就列出最相关的选项(Postgres、MySQL、MongoDB、BigQuery、Snowflake、Redshift),让他们选择。

对于基于 OAuth 的源(Hubspot、Salesforce、Google Ads),向导条目会提示 OAuth 流程。这类源通常需要用户在 PostHog UI 中授权,而不是粘贴凭据——请说明这一点,并引导他们前往源设置页面,而不要尝试在聊天中收集令牌。OAuth 关乎_身份验证_,而非数据流动方式;OAuth 源仍使用轮询批量同步,而不是 Webhook。

向用户收集所需凭据。不要询问超出向导条目所列必需项的字段——如果源不需要 port,询问这个字段只会让用户困惑。

步骤 2 — 验证凭据并发现表

调用 external-data-sources-db-schema,并传入 source_type 和所有凭据字段。此调用会同时完成两件事:

  1. 根据实时源验证凭据。如果有误(主机错误、密码错误、权限被拒绝),则返回带有 message 的 400 错误。原样展示错误信息——它通常能提供可采取行动的提示(“用户 'x' 的密码身份验证失败”)。
  2. 如果凭据有效,则返回一个表条目数组。每个条目:
{
  "table": "orders",
  "should_sync": false,
  "rows": 1_250_000,
  "incremental_available": true,   # can do sync_type=incremental
  "append_available": true,        # can do sync_type=append
  "cdc_available": true,           # can do sync_type=cdc  (null = not enabled for team)
  "supports_webhooks": false,      # can do sync_type=webhook for real-time push
  "incremental_fields": [          # candidates: usually updated_at, created_at, id
    {"field": "updated_at", "type": "datetime", "label": "updated_at", ...},
    {"field": "created_at", "type": "datetime", ...},
    {"field": "id", "type": "integer", ...}
  ],
  "detected_primary_keys": ["id"],
  "available_columns": [{"field": "id", "type": "integer", "nullable": false}, ...],
  "description": "..."
}

将这些信息呈现给用户。不要直接输出原始 JSON,而要概述:发现了哪些表、行数,以及每张表推荐的默认同步方法(参见同步类型决策指南)。

步骤 3 — 确认每个表的同步配置

对于用户想要同步的每个表,选择一种 sync_type。详细规则请参阅 sync-type 决策指南,简而言之:

  • 小型/维度表(<50k 行,且没有自然排序列): full_refresh — 简单且始终正确。
  • 包含 updated_at / modified_at 的大型表: incremental — 每次同步的成本低得多。
  • 只追加且不可变的表(日志、事件): 如果可用,使用 append — 保留历史记录。
  • 启用了 CDC 的 Postgres,且需要近实时同步: cdc — 需要主键和 Postgres 前置条件。
  • 支持 Webhook 的数据源(目前为 Stripe): 若要实现近实时摄取,请对 supports_webhooks: true 的表设置 sync_type: "webhook",然后将 Webhook 注册为创建后的步骤(见下文步骤 6)。 同一数据源中不支持 Webhook 的表仍需要使用批量 sync_type。

对于将使用 incremental / append / cdc 的每个 schema,还需要:

  • incremental_field — 用于跟踪高水位标记排序的列。从 db-schema 返回的 incremental_fields 列表中选择。优先选择 updated_at 而非 created_at(updated_at 能捕获延迟到达的更新;created_at 则会漏掉这些更新)。对于只有整数列的表,使用单调递增的主键。
  • incremental_field_type — 必须与所选字段的类型匹配(datetime、timestamp、date、integer、numeric、objectid)。
  • primary_key_columns — CDC 必填。使用 db-schema 中的 detected_primary_keys。
步骤 4 — 选择合适的前缀

数据源的 prefix 会添加到 HogQL 中的表名之前。表名最终为 {prefix}_{table_name}。

  • 如果只有一个该类型的数据源,默认使用小写的数据源类型:stripe、postgres。
  • 如果用户已有一个 Postgres 数据源,请选择有区分度的名称:postgres_prod、postgres_analytics。
  • 使用小写字母并以下划线分隔。该前缀会成为用户编写的每个 HogQL 查询的一部分。

创建前请与用户确认前缀——之后可以更改,但会重命名每个表。

步骤 5 — 创建数据源

使用以下参数调用 external-data-sources-create:

{
  "source_type": "Postgres",
  "prefix": "postgres_prod",
  "payload": {
    "host": "...",
    "port": "5432",
    "dbname": "...",
    "user": "...",
    "password": "...",
    "schema": "public",
    "schemas": [
      {
        "name": "orders",
        "should_sync": true,
        "sync_type": "incremental",
        "incremental_field": "updated_at",
        "incremental_field_type": "datetime",
        "primary_key_columns": ["id"]
      },
      {
        "name": "users",
        "should_sync": true,
        "sync_type": "full_refresh"
      },
      {
        "name": "audit_log",
        "should_sync": false
      }
    ]
  }
}

schemas 数组的规则:

  • 必须包含 db-schema 返回的每个表,包括用户不想同步的表(将 should_sync: false)。用户未提及的表默认设置为 should_sync: false。
  • 仅当 should_sync: true 时才需要 sync_type。
  • 当 sync_type 为 incremental 或 append 时,必须提供 incremental_field / incremental_field_type。
  • 当 sync_type 为 cdc 时,必须提供 primary_key_columns。

成功后,你会获得一个带有新 id 的数据源。首次同步会自动触发。

步骤 6 — 注册 webhook(仅当某个 schema 的 sync_type 为 "webhook" 时)

Webhook 类型的 schema 不会仅凭存在就开始接收数据——外部服务需要知道要向哪里 POST 事件,PostHog 也需要知道如何验证这些事件。这是在创建数据源后进行的第二次调用,不属于 external-data-sources-create 载荷的一部分。务必在告知用户设置已完成之前执行此操作,否则用户会听到“同步正在运行”,但推送通道其实尚未注册。

仅当数据源上至少有一个 schema 的 sync_type 为 "webhook" 且 should_sync: true 时,才需要执行此步骤。目前只有 Stripe 支持此流程;其他情况均跳过此步骤。

调用 create-webhook 前,先检查 external-data-sources-webhook-info-retrieve({id})。如果返回 exists: true,请勿再次调用 create-webhook——每次成功调用都会注册一个新的外部端点,从而导致重复投递。

  1. 调用 external-data-sources-create-webhook-create({id})。PostHog 会:

    • 创建用于接收 webhook POST 请求的 HogFunction,
    • 根据外部事件类型和 PostHog schema ID 构建 schema_mapping,
    • 调用数据源的 API(例如 Stripe),注册 webhook URL 并订阅相关事件,
    • 在 Stripe 上自动捕获 signing_secret 并安全存储。

    返回 {success, webhook_url, error}。如果成功,请将 webhook_url 告知用户以供记录——但他们无需在任何地方粘贴此 URL;注册已完成。

  2. 如果 success: false 且返回类似“API key doesn't have permission to create webhooks”的权限错误:

    • HogFunction 仍会创建,但处于禁用状态。
    • 请用户在数据源的控制面板中使用返回的 webhook_url 手动创建 webhook。
    • 请用户从数据源的 webhook 设置中复制 signing secret。
    • 调用 external-data-sources-update-webhook-inputs-create({id}, {inputs: {signing_secret: "whsec_..."}}) 进行存储。HogFunction 会获取此密钥并验证传入的载荷。
  3. 使用 external-data-sources-webhook-info-retrieve({id}) 验证。运行正常的 webhook 应满足:exists: true、external_status.status: "enabled",且没有 error。

Webhook 是批量同步的补充。启用 webhook 的 schema 首次加载仍通过轮询完成(完成后 initial_sync_complete 会变为 true);此后,webhook 会成为主要的数据接入方式。Webhook schema 仍会有一个 sync_frequency,用于安排定期批量刷新作为安全保障。这是预期行为——无需“修复”。

步骤 7 — 确认并说明后续情况

创建完成后(对于 webhook schema,则在完成步骤 6 后):

  • 调用 external-data-schemas-list,向用户展示初始状态。
  • 说明:每个已启用的 schema 都会进入 Running 状态,然后在首次同步完成后变为 Completed。首次同步可能需要几秒到几小时,具体取决于行数——数百万行的表也可以,只是速度较慢。
  • 告知用户如何查询:在 HogQL 中执行 SELECT * FROM {prefix}_{table_name} LIMIT 10。
  • 询问用户是否希望你几分钟后再检查一次,以确认首次同步成功。

Postgres 的 CDC 设置(可选,按需执行)

如果用户希望从 Postgres 进行近实时复制:

  1. 调用 db-schema 前,使用用户的 Postgres 凭据运行 external-data-sources-check-cdc-prerequisites-create。它会返回 {valid, errors[]},列出所有缺失项(wal_level、复制槽、发布、权限)。
  2. 如果 valid: false,请列出错误并让用户在 Postgres 端修复。不要尝试创建一个会立即失败的 CDC 数据源。
  3. 前置条件通过后,继续执行 db-schema 并创建数据源。对需要 CDC 的表设置 sync_type: "cdc",并为每张表提供 primary_key_columns(CDC 必须包含这些列)。

重要说明

  • 创建前务必使用 db-schema 验证凭证。 创建端点会接受无效凭证,随后异步失败——数据源会以 Error 状态出现在列表中,且没有任何表。跳过验证步骤,只是把失败推到了后台。
  • 创建前先展示表列表。 大型数据库可能有数百张表。不要自动全选——行数和相关性会影响计费。让用户明确选择。
  • 不要虚构架构。 schemas 数组中的每个条目都必须对应 db-schema 响应中的真实表。除非 db-schema 找到了订单表,否则不能“顺便添加一个订单表”。
  • 新数据源会同步到 PostHog 数据仓库。 这是默认设置,无需配置:未配置目标位置的数据源只会写入此处,不会写入其他位置。部分项目也可以将数据源的表发送到自己的数据库(如果项目启用了此功能,external-data-sources-destinations-retrieve 会显示数据源写入的位置)。这需要单独设置,绝不能作为创建数据源的一部分——向已完成同步的数据源添加目标位置后,在重新同步表之前,该目标位置不会有任何历史数据;重新同步会对数据源写入的每个目标位置计费。
  • 前缀至关重要。 用户今后针对这些表编写的每条 HogQL 查询都会用到它。请选一个简短、描述性强且尚未被占用的前缀。
  • 凭证优先使用安全的连接链接。 使用 data-warehouse-source-connect-link,让用户在浏览器中完成身份验证——连接页面会呈现数据源的完整连接表单(包括 OAuth 和凭证选项),并保存结果,而不会创建数据源。不要在聊天中收集 OAuth 令牌或数据库密码;将 credential_id 引用传递给 setup——数据源始终通过 setup 创建,而不是通过 UI 创建。(也可以直接通过其 id 键传入已连接的 OAuth 集成,例如 {"hubspot_integration_id": 123}。)
  • Webhook 需要在创建后单独设置。 在架构上设置 sync_type: "webhook" 不会注册 webhook——需要调用 create-webhook。对于 webhook 类型的架构,务必依次执行 create → create-webhook → webhook-info;绝不能让 webhook 架构处于未注册状态(否则不会收到事件)。
  • Webhook 支持因数据源而异,且覆盖范围有限。 目前只有 Stripe 实现了 WebhookSource。不要承诺 Hubspot、Salesforce 或 Postgres 支持 webhook——它们会使用轮询同步。
  • 行数决定计费。 数据仓库同步按同步的行数计费。每小时同步一个频繁产生数据、包含 5 亿行的 events 表,与每天同步一个包含 1 万行的维度表,成本截然不同。请标记大型表,并默认提供更长的同步频率(sync_frequency: "24hour")。

评论

支持 Markdown