microsoft / microsoft/PowerPlatform-DataverseClient-Python

tables.create / add_columns cannot set column constraints (MaxLength, MinValue/MaxValue, Format, RequiredLevel, DisplayName)

未关闭
#194 0 条评论 0 个 reaction 已指派 1 人 在 GitHub 查看

@vrathee-msft 已经在做这个了。

开始于 2026年8月17日。

enhancement
主要语言
Python
星标
60
派生
23
平均合并
13 小时 53 分钟
30 天内合并 PR
3

描述

Summary

client.tables.create(...) and client.tables.add_columns(...) accept a column spec of {schema_name: type} where the value is only a type string (or an Enum subclass for optionsets). There is no way to set per-column constraints -- MaxLength, MinValue/MaxValue, Format/FormatName, Precision, RequiredLevel, or a custom DisplayName. Every constraint is hardcoded per type.

Evidence (main @ 5601657)

src/PowerPlatform/Dataverse/data/_odata_base.py::_attribute_payload:

  • Rejects any non-str / non-Enum spec: raise ValueError("... expected str or Enum subclass").
  • Hardcodes constraints per type: string -> MaxLength: 200; memo -> MaxLength: 4000; int -> MinValue: -2147483648, MaxValue: 2147483647; decimal/double -> fixed Min/Max + Precision; RequiredLevel: {"Value": "None"} on all branches; DisplayName derived from the schema-name suffix.

No public create_attribute / raw-metadata / generic-request method exists in the tables API (only create, add_columns, remove_columns, create_alternate_key), so there is no managed escape hatch either.

Impact

To create, for example, a Rating column limited to 1-5 or a Comment column with MaxLength=2000, callers must drop to the raw Web API EntityDefinitions({id})/Attributes endpoint and hand-build the payload -- including the @odata.type derived-type discriminator and using PUT (not PATCH) for updates. On hosts where the Dataverse CLI cannot run (ChatGPT web / Codex sandbox -- no .NET runtime), the SDK is the primary path, so this gap forces error-prone hand-rolled metadata calls for a very common ask ("create a table with a bounded rating and a sized text field").

Proposed change (backward-compatible)

Extend the column-spec value to also accept a dict, keeping str / Enum working exactly as today:

client.tables.create("cfb_CustomerFeedback", {
    "cfb_Name": "string",                                         # unchanged
    "cfb_Rating":  {"type": "int",  "min_value": 1, "max_value": 5},
    "cfb_Comment": {"type": "memo", "max_length": 2000, "display_name": "Comment"},
})

_attribute_payload builds the base payload for type, then applies the provided overrides:

  • max_length -> MaxLength
  • min_value / max_value -> MinValue / MaxValue
  • precision -> Precision
  • format -> Format (int/date) or FormatName.Value (string/memo)
  • required -> RequiredLevel.Value (None / ApplicationRequired / Recommended)
  • display_name -> DisplayName label

The @odata.type discriminator is already stamped correctly, so this needs no endpoint changes.

Touchpoints

  • data/_odata_base.py::_attribute_payload (core -- shared by the sync + async paths).
  • Docstrings / typing for operations/tables.py + aio/operations/async_tables.py (create, add_columns) and operations/batch.py.
  • Unit tests mirroring the existing _attribute_payload type tests (add override cases).
  • README + CHANGELOG per the repo maintenance rules.

Acceptance

  • {"type": "memo", "max_length": 2000} produces a MemoAttributeMetadata payload with MaxLength: 2000.
  • {"type": "int", "min_value": 1, "max_value": 5} produces an IntegerAttributeMetadata payload with those bounds.
  • str and Enum specs behave exactly as before (no breaking change).
  • Unit tests cover the overrides and the unchanged str/Enum paths.

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。