---
title: "External Attribute Sync"
description: "External Attribute Sync 会把选定的 Flow Attribute 写入你自己的 PostgreSQL 表。每个目标称为一个 Attribute Store。Dex 以异步方式逐个 Flow 写入最新状态，并采用至少一次尝试语义，因此每种目标写入都具有幂等性。"
canonical_url: "https://docs.superdurable.io/zh-Hans/primitives/components/external-attribute-sync/"
source: "docs/i18n/zh-Hans/docusaurus-plugin-content-docs/current/primitives/components/external-attribute-sync.mdx"
locale: "zh-Hans"
---

# External Attribute Sync

External Attribute Sync 会把选定的 Flow Attribute 写入你自己的 PostgreSQL 表。每个目标称为一个 Attribute Store。Dex 以异步方式逐个 Flow 写入最新状态，并采用至少一次尝试语义，因此每种目标写入都具有幂等性。

目前只支持 PostgreSQL 作为 Attribute Store。Redis 支持由 [issue 616](https://github.com/superdurable/dex/issues/616) 跟踪。

Dex 不会创建、迁移或回填目标。请在启动 server 前创建 SQL 表。

## 与其他组件的关系

External Attribute Sync 是 [server](https://docs.superdurable.io/zh-Hans/primitives/components/server.md) 的功能。Flow 用 **syncToAttributeStore** 标记 Attribute，并在 **FlowConfig** 中列出已配置的 store 名称。server-zd 随后把这个 Attribute 写入该 store 的表。你的 [应用](https://docs.superdurable.io/zh-Hans/primitives/components/application.md) 和报表用 SQL 查询这些表。

## 配置

```yaml
attributeStore:
  stores:
    reporting:
      type: postgres
      dsn: postgres://user:password@host/database
      tableName: public.flow_attributes
    orders:
      type: postgres
      dsn: postgres://user:password@host/database
      tableName: public.orders
      rowKey: order-{customer_id}-{order_id}
      columnNaming: snake_case
      attributeMaps:
        LineItems:
          tableName: public.order_line_items
          instanceKeyColumn: line_item_id
  schemaSyncInterval: 1m
  syncBatchSize: 100
  syncAttemptTimeout: 30s
  syncRetryPolicy:
    initialInterval: 100ms
    maximumInterval: 30s
    backoffCoefficient: 2
    maximumAttempts: 0
    totalDuration: 1h
```

每个 store 都必须配置 **type: postgres**、**tableName** 和 DSN（**dsn** 或环境变量）。server-zd 绝不会记录 DSN。**tableName** 接受 **table** 或 **schema.table**。Dex 会解析并引用标识符，Attribute value 始终通过 driver 参数传递。每个键及其默认值见英文的 [Attribute Store sync configuration](https://docs.superdurable.io/zh-Hans/reference/server/attribute-store-sync.md#attribute-store-configuration)。

## 交付与重试

Attribute Sync 保存最新状态，而不是 event history。发生不确定失败后，后续写入可能重复。因此 upsert 使用 Flow ID 作为幂等 key。

写入从不阻塞 Step、RPC 或 SetAttributes 的提交。失败的写入会重试到 **syncRetryPolicy.totalDuration**，之后丢弃并输出 error log。Dex 不会自动重放旧 Attribute，也不会为新配置的 store 自动 backfill。过滤写入、目标缺失和重试耗尽都会输出 error log。

fencing 表、关闭行为、重试、metrics、row key、AttributeMap 表和 SQL 类型契约详见英文 Server 参考中的 [Attribute Store sync](https://docs.superdurable.io/zh-Hans/reference/server/attribute-store-sync.md)。

<a id="attribute-store-local-development"></a>

## 本地开发

**dex-server-zd dev** 在本地运行一个使用内嵌对象存储的节点。它的 **--attribute-store-config** 参数只读取 YAML 文件中的 **attributeStore** 一节。这一节至少要定义一个 store。**--config** 覆盖文件不能同时设置 **attributeStore**。

```bash
dex-server-zd dev --data-dir ./zd-data --attribute-store-config ./attribute-store.yaml
```

数据库仍然需要这些表和 fencing 表。**dexcli dev --attribute-store-config** 会把文件传给这个参数。
