Skip to content

Commit 4334298

Browse files
Merge pull request #51 from microsoft/user/tpellissier/prefix-with-schemaname
Use prefixed table name, add case-insensitivity
2 parents 1d469ed + 87b4faf commit 4334298

10 files changed

Lines changed: 775 additions & 1036 deletions

File tree

README.md

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ The SDK provides a simple, pythonic interface for Dataverse operations:
9999
| Concept | Description |
100100
|---------|-------------|
101101
| **DataverseClient** | Main entry point for all operations with environment connection |
102-
| **Records** | Dataverse records represented as Python dictionaries with logical field names |
103-
| **Logical Names** | Use table logical names (`"account"`) and column logical names (`"name"`) |
102+
| **Records** | Dataverse records represented as Python dictionaries with column schema names |
103+
| **Schema names** | Use table schema names (`"account"`, `"new_MyTestTable"`) and column schema names (`"name"`, `"new_MyTestColumn"`). See: [Table definitions in Microsoft Dataverse](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/entity-metadata) |
104104
| **Bulk Operations** | Efficient bulk processing for multiple records with automatic optimization |
105105
| **Paging** | Automatic handling of large result sets with iterators |
106106
| **Structured Errors** | Detailed exception hierarchy with retry guidance and diagnostic information |
107+
| **Customization prefix values** | Custom tables and columns require a customization prefix value to be included for all operations (e.g., `"new_MyTestTable"`, not `"MyTestTable"`). See: [Table definitions in Microsoft Dataverse](https://learn.microsoft.com/en-us/power-apps/developer/data-platform/entity-metadata) |
107108

108109
## Examples
109110

@@ -175,40 +176,75 @@ for record in results:
175176
print(record["name"])
176177

177178
# OData query with paging
179+
# Note: filter and expand parameters are case sensitive
178180
pages = client.get(
179181
"account",
180-
select=["accountid", "name"],
181-
filter="statecode eq 0",
182+
select=["accountid", "name"], # select is case-insensitive (automatically lowercased)
183+
filter="statecode eq 0", # filter must use lowercase logical names (not transformed)
182184
top=100
183185
)
184186
for page in pages:
185187
for record in page:
186188
print(record["name"])
189+
190+
# Query with navigation property expansion (case-sensitive!)
191+
pages = client.get(
192+
"account",
193+
select=["name"],
194+
expand=["primarycontactid"], # Navigation property names are case-sensitive
195+
filter="statecode eq 0" # Column names must be lowercase logical names
196+
)
197+
for page in pages:
198+
for account in page:
199+
contact = account.get("primarycontactid", {})
200+
print(f"{account['name']} - Contact: {contact.get('fullname', 'N/A')}")
187201
```
188202

203+
> **Important**: When using `filter` and `expand` parameters:
204+
> - **`filter`**: Column names must use exact lowercase logical names (e.g., `"statecode eq 0"`, not `"StateCode eq 0"`)
205+
> - **`expand`**: Navigation property names are case-sensitive and must match the exact server names
206+
> - **`select`** and **`orderby`**: Case-insensitive; automatically converted to lowercase
207+
189208
### Table management
190209

191210
```python
192-
# Create a custom table
193-
table_info = client.create_table("Product", {
194-
"code": "string",
195-
"price": "decimal",
196-
"active": "bool"
211+
# Create a custom table, including the customization prefix value in the schema names for the table and columns.
212+
table_info = client.create_table("new_Product", {
213+
"new_Code": "string",
214+
"new_Price": "decimal",
215+
"new_Active": "bool"
197216
})
198217

199-
# Add columns to existing table
200-
client.create_columns("Product", {"category": "string"})
218+
# Create with custom primary column name and solution assignment
219+
table_info = client.create_table(
220+
table_schema_name="new_Product",
221+
columns={
222+
"new_Code": "string",
223+
"new_Price": "decimal"
224+
},
225+
solution_unique_name="MyPublisher", # Optional: add to specific solution
226+
primary_column_schema_name="new_ProductName" # Optional: custom primary column (default is "{customization prefix value}_Name")
227+
)
228+
229+
# Add columns to existing table (columns must include customization prefix value)
230+
client.create_columns("new_Product", {"new_Category": "string"})
231+
232+
# Remove columns
233+
client.delete_columns("new_Product", ["new_Category"])
201234

202235
# Clean up
203-
client.delete_table("Product")
236+
client.delete_table("new_Product")
204237
```
205238

239+
> **Important**: All custom column names must include the customization prefix value (e.g., `"new_"`).
240+
> This ensures explicit, predictable naming and aligns with Dataverse metadata requirements.
241+
206242
### File operations
207243

208244
```python
209245
# Upload a file to a record
210246
client.upload_file(
211-
logical_name="account",
247+
table_schema_name="account",
212248
record_id=account_id,
213249
file_name_attribute="new_document",
214250
path="/path/to/document.pdf"

0 commit comments

Comments
 (0)