microsoft / microsoft/PowerPlatform-DataverseClient-Python
tables.create / add_columns cannot set column constraints (MaxLength, MinValue/MaxValue, Format, RequiredLevel, DisplayName)
@vrathee-msft ya está trabajando en esto.
Desde el 17/8/2026.
- Lenguaje dominante
- Python
- Estrellas
- 60
- Forks
- 23
- Merge medio
- 13 h 53 min
- PR fusionados (30 d)
- 3
Descripción
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-Enumspec: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;DisplayNamederived 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->MaxLengthmin_value/max_value->MinValue/MaxValueprecision->Precisionformat->Format(int/date) orFormatName.Value(string/memo)required->RequiredLevel.Value(None/ApplicationRequired/Recommended)display_name->DisplayNamelabel
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) andoperations/batch.py. - Unit tests mirroring the existing
_attribute_payloadtype tests (add override cases). - README + CHANGELOG per the repo maintenance rules.
Acceptance
{"type": "memo", "max_length": 2000}produces a MemoAttributeMetadata payload withMaxLength: 2000.{"type": "int", "min_value": 1, "max_value": 5}produces an IntegerAttributeMetadata payload with those bounds.strandEnumspecs behave exactly as before (no breaking change).- Unit tests cover the overrides and the unchanged str/Enum paths.
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Evaluación
Este issue todavía no se ha evaluado.