自定义表和列

SDK 支持对 自定义表 和列执行创建、更新和删除(CUD)操作,支持可选的解决方案关联,以及检索和列出表定义。

让我们看看使用自定义表的示例代码。

# Create a custom table, including the customization prefix value in the schema names for the table and columns.
table_info = client.tables.create("new_Product", {
    "new_Code": "string",
    "new_Description": "memo",
    "new_Price": "decimal",
    "new_Active": "bool"
})

# Create with custom primary column name and solution assignment
table_info = client.tables.create(
    "new_Product",
    columns={
        "new_Code": "string",
        "new_Price": "decimal"
    },
    solution="MyPublisher",  # Optional: add to specific solution
    primary_column="new_ProductName",  # Optional: custom primary column (default is "{customization prefix value}_Name")
)

# Get table information
info = client.tables.get("new_Product")
print(f"Logical name: {info['table_logical_name']}")
print(f"Entity set: {info['entity_set_name']}")

# List all tables
tables = client.tables.list()
for table in tables:
    print(table)

# Add columns to existing table (columns must include customization prefix value)
client.tables.add_columns("new_Product", {"new_Category": "string"})

# Remove columns
client.tables.remove_columns("new_Product", ["new_Category"])

# List all columns (attributes) for a table to discover schema
columns = client.tables.list_columns("account")
for col in columns:
    print(f"{col['LogicalName']} ({col.get('AttributeType')})")

# List only specific properties
columns = client.tables.list_columns(
    "account",
    select=["LogicalName", "SchemaName", "AttributeType"],
    filter="AttributeType eq 'String'",
)

# Clean up
client.tables.delete("new_Product")

支持的列类型

create() 和 add_columns() 接受以下类型字符串。

类型 接受的别名
string text
memo multiline
int integer
decimal money
float double
bool boolean
datetime date
file —

对于选项集(choice)列,应直接将 Enum 的子类(或其成员具有整数值的 IntEnum)作为列类型值传递,而不是传递字符串。 SDK 使用类成员定义选项集值。

from enum import IntEnum

class Priority(IntEnum):
    LOW = 1
    MEDIUM = 2
    HIGH = 3

table_info = client.tables.create("new_Task", {
    "new_Title": "string",
    "new_Priority": Priority,   # optionset column
})

设置列约束

若要设置长度、数字范围、精度、格式、所需级别或显示名称等约束,请传递字典而不是裸类型字符串。 该 type 键包含列类型,其余键设置约束。

Key 适用对象 Description
max_length string、memo 最大字符数。
min_value、max_value int、decimal、money、float 允许的数字范围。
precision decimal、money、float 小数位数。
format string、int、datetime 文本列(例如,Email、Url 或 Phone)的格式名称,或整数和日期/时间列的格式。
required 全部 所需级别: None、 Recommended或 ApplicationRequired。
display_name 全部 显示制造商门户和应用中显示的标签。
# Pass a dict spec to set constraints; a bare type string still works for simple columns.
client.tables.create("new_Feedback", {
    "new_Rating":  {"type": "int",  "min_value": 1, "max_value": 5},
    "new_Comment": {"type": "memo", "max_length": 2000, "display_name": "Comment"},
})

可以在任何接受列类型的位置使用 dict 规范,包括 add_columns() 和批量创建列。

更新列定义

使用 update_column 更改一列的约束,或使用 update_columns 在一次调用中更改多列的约束。 两者都接受与 create 相同的替代键。 SDK 会在发送任何请求之前验证每个规范,因此无效条目会导致整个调用失败,而不会更改前面的列。

# Widen one column
client.tables.update_column("new_Feedback", "new_Comment", {"max_length": 4000})

# Update several columns at once
client.tables.update_columns("new_Feedback", {
    "new_Rating":  {"max_value": 10},
    "new_Comment": {"display_name": "Customer Comment"},
})

更新将检索完整的列定义,应用更改,并使用 MSCRM.MergeLabels 标头将完整定义发送回 Dataverse。 将保留其他语言的标签,因此,更改一个属性(例如,max_length)不会更改该列的其余部分。

读取类型化的列元数据

默认情况下, list_columns 并 get_column 返回基本属性元数据。 传递typed=True以在单个请求中检索特定于类型的定义,其中包括文本列的MinValue属性,或数值列的MaxValue和MaxLength属性。

# One column, with its type-specific fields
col = client.tables.get_column("new_Feedback", "new_Comment", typed=True)
print(col["MaxLength"])   # 4000

# All columns, each with type-specific fields
cols = client.tables.list_columns("new_Feedback", typed=True)

Note

该 filter 参数仅适用于默认(typed=False)列表。 结合filter和typed=True会导致一个ValueError。

TableInfo 返回对象

方法 client.tables.create() 返回 对象 TableInfo 。 直接访问其属性,或使用旧版字典键表示法以保持向后兼容性。

table_info = client.tables.create("new_Product", {"new_Code": "string"})

print(table_info.schema_name)       # new_Product
print(table_info.logical_name)      # new_product
print(table_info.entity_set_name)   # new_products
print(table_info.columns_created)   # ['new_Code', ...]

# Legacy dict-key access still works
print(table_info["table_schema_name"])

和add_columns()remove_columns()方法返回它们创建或删除的列架构名称的列表。 该方法 get() 返回表元数据,或者 None 如果表不存在,这使得它可用于存在检查。

替换键

备用键使用一个或多个业务列来标识记录,而不是使用 Dataverse 生成的 GUID。 upsert 操作需要备用键。 在Power Apps创建者门户中的表>键下定义它们,或者通过使用client.tables.create_alternate_key编程方式定义它们。

# Create an alternate key on the accountnumber column
key = client.tables.create_alternate_key(
    "account",
    "account_accountnumber_ak",
    ["accountnumber"],
    display_name="Account Number",
)
print(f"Created key {key.schema_name} ({key.metadata_id}), status={key.status}")

# The key status transitions from Pending to Active asynchronously - poll before upserting
for k in client.tables.get_alternate_keys("account"):
    if k.schema_name == "account_accountnumber_ak":
        print(f"{k.schema_name}: {k.status}")

Important

从 Pending 过渡到 Active 不是即时的。 在创建后立即检查密钥状态,并等待其变为 Active 后再发出 upsert 请求。 如果没有活动的备用密钥,Dataverse 将拒绝出现 400 错误的 upsert 请求。

Important

所有自定义列名都必须包括自定义前缀值(例如“new_”)。 此要求可确保显式、可预测的命名,并符合 Dataverse 元数据要求。

有关处理自定义表元数据的详细信息:

  • tables.create 返回描述 TableInfo 新表的对象。 它不返回记录 ID。
  • 当表不存在时,tables.get 返回 None,这使架构设置具有幂等性。
  • tables.add_columns 并 tables.remove_columns 返回已更改的列名列表。
  • tables.list_columns 返回使用 Web API PascalCase 属性名称的原始属性元数据字典,例如 LogicalName 和 AttributeType。

若要在表中创建、读取、更新和删除 记录 ,请参阅 “处理数据”。

另见