Repository navigation
tables.create() does not expose primary column logical name, causing CRUD payload confusion #148
Description
Summary
When using tables.create() to create custom tables and then dataframe.create() to populate records, it is unclear what column logical names to use in the record payload. The SDK's tables.create() documentation does not specify the resulting logical names that Dataverse assigns, leading to confusion and 400 errors.
Problem
After calling tables.create("demo_abc123_Customer", {"demo_abc123_Customer_Revenue": "money"}), the resulting column's schema name is demo_abc123_Customer_Revenue, but the logical name (used in CRUD payloads, $select, $filter, etc.) is demo_abc123_customer_revenue (fully lowercased).
However, the default primary column created automatically has schema name demo_abc123_Name with logical name demo_abc123_name -- NOT demo_abc123_customer_name. The prefix for the primary column is the customization prefix extracted from the table schema name, not the full table name.
This means:
- Custom columns defined by the user: logical name = lowercase of passed schema name (e.g.,
demo_abc123_customer_revenue) - Default primary column: logical name =
{customization_prefix}_name(e.g.,demo_abc123_name) - There is no documentation or return value from
tables.create()that tells the user what primary column logical name was created
Steps to Reproduce
from PowerPlatform.Dataverse.client import DataverseClient
with DataverseClient(url, credential) as client:
# Step 1: Create table
result = client.tables.create(
"demo_abc123_Customer",
{"demo_abc123_Customer_Revenue": "money"},
)
# Step 2: Try to create a record -- what is the name column called?
import pandas as pd
df = pd.DataFrame([{
"demo_abc123_Customer_name": "Contoso", # WRONG - 400 error
# "demo_abc123_name": "Contoso", # CORRECT - but not obvious
"demo_abc123_Customer_Revenue": 5000000,
}])
client.dataframe.create("demo_abc123_Customer", df)
# Error: Invalid property 'demo_abc123_customer_name'Expected Behavior
Either:
tables.create()should return the primary column logical name in its response (theTableInfoalready hascolumns_createdbut it doesn't include the auto-created primary column)- Documentation should clearly state that the primary column logical name follows the pattern
{customization_prefix}_namewhere the prefix is extracted from the table schema name - Consider adding a
primary_column_namefield to theTableInforeturn type
Actual Behavior
tables.create()returnsTableInfowithcolumns_createdlisting only explicitly defined columns, not the auto-created primary name column- No documentation explains the primary column naming convention
- Users have to query entity metadata (
EntityDefinitions) to discover the primary column logical name
Related Issues
- Better data type specification #76 (Better data type specification) -- related to column definition UX
- @odata.bind problem with same column and table names #77 (@odata.bind problem with same column and table names) -- related to column naming confusion
Context
Discovered while building the pro-dev quick start example (examples/advanced/prodev_quick_start.py) which creates 4 custom tables and populates them via client.dataframe.create(). The example could not reliably construct record payloads because the primary column logical name was not discoverable from the SDK.
Suggested Fix
- Include the primary column logical name in
TableInfo.columns_created(or a newprimary_columnfield) - Add a note in
tables.create()docstring explaining: "The default primary column logical name is{prefix}_namewhere{prefix}is the customization prefix from the table schema name" - Consider a
tables.get_columns(table_name)convenience method that returns column metadata including logical names
Activity
Expose primary_name_attribute in TableInfo, fix prodev example E2E
saurabhrb commentedon Mar 17, 2026
Fixed in commit 5280c46 on PR #98.
Changes:
Usage after fix:
\\python
result = client.tables.create('demo_Customer', {'demo_Customer_Revenue': 'money'})
print(result.primary_name_attribute) # e.g., 'demo_name'
Use this to construct correct record payloads
\\
Verified E2E: prodev_quick_start.py now creates 4 tables, 3 relationships, 13 records, queries, updates, deletes, and cleans up successfully.
Expose primary_name_attribute in TableInfo, fix prodev example E2E
saurabhrb commentedon Mar 17, 2026
Resolved in PR #98 (commit 639f0dd).
The fix exposes PrimaryNameAttribute and PrimaryIdAttribute from Dataverse EntityDefinitions metadata through the existing tables.create() and tables.get() API, making the primary column logical name discoverable without guessing.
Root cause: The SDK's prefix extraction for default primary column naming used split('',1)[0] which only works for single-segment publisher prefixes (e.g., new, cr7b4_). Multi-segment prefixes (e.g., demo_614322_) produced incorrect column names. The fix avoids this entirely by reading the actual metadata from the server.
Expose primary_name_attribute in TableInfo, fix prodev example E2E
Expose primary_name_attribute in TableInfo metadata (fixes #148)
Expose primary_name_attribute in TableInfo metadata (fixes #148)
Add client.dataframe namespace for pandas DataFrame CRUD operations (#98