Skip to content

Commit 2ee0a7c

Browse files
tpellissierclaude
andcommitted
Move relationship methods to client.tables namespace
- Add create_one_to_many, create_many_to_many, delete_relationship, get_relationship, and create_lookup_field to TableOperations - Remove flat relationship methods from DataverseClient (not yet published) - Update relationships example and README to use client.tables.* - Update tests to use namespaced API Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 6b8353b commit 2ee0a7c

6 files changed

Lines changed: 387 additions & 303 deletions

File tree

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ The SDK provides a simple, pythonic interface for Dataverse operations:
112112
| Concept | Description |
113113
|---------|-------------|
114114
| **DataverseClient** | Main entry point; provides `records`, `query`, and `tables` namespaces |
115-
| **Namespaces** | Operations are organized into `client.records` (CRUD), `client.query` (queries), and `client.tables` (metadata) |
115+
| **Namespaces** | Operations are organized into `client.records` (CRUD), `client.query` (queries), and `client.tables` (metadata & relationships) |
116116
| **Records** | Dataverse records represented as Python dictionaries with column schema names |
117117
| **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) |
118118
| **Bulk Operations** | Efficient bulk processing for multiple records with automatic optimization |
@@ -287,7 +287,7 @@ relationship = OneToManyRelationshipMetadata(
287287
referenced_attribute="new_departmentid",
288288
)
289289

290-
result = client.create_one_to_many_relationship(lookup, relationship)
290+
result = client.tables.create_one_to_many_relationship(lookup, relationship)
291291
print(f"Created lookup field: {result['lookup_schema_name']}")
292292

293293
# Create a many-to-many relationship: Employee (N) <-> Project (N)
@@ -298,23 +298,23 @@ m2m_relationship = ManyToManyRelationshipMetadata(
298298
entity2_logical_name="new_project",
299299
)
300300

301-
result = client.create_many_to_many_relationship(m2m_relationship)
301+
result = client.tables.create_many_to_many_relationship(m2m_relationship)
302302
print(f"Created M:N relationship: {result['relationship_schema_name']}")
303303

304304
# Query relationship metadata
305-
rel = client.get_relationship("new_Department_Employee")
305+
rel = client.tables.get_relationship("new_Department_Employee")
306306
if rel:
307307
print(f"Found: {rel['SchemaName']}")
308308

309309
# Delete a relationship
310-
client.delete_relationship(result['relationship_id'])
310+
client.tables.delete_relationship(result['relationship_id'])
311311
```
312312

313313
For simpler scenarios, use the convenience method:
314314

315315
```python
316316
# Quick way to create a lookup field with sensible defaults
317-
result = client.create_lookup_field(
317+
result = client.tables.create_lookup_field(
318318
referencing_table="contact", # Child table gets the lookup field
319319
lookup_field_name="new_AccountId",
320320
referenced_table="account", # Parent table being referenced

examples/advanced/relationships.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ def log_call(description):
4141

4242
def delete_relationship_if_exists(client, schema_name):
4343
"""Delete a relationship by schema name if it exists."""
44-
rel = client.get_relationship(schema_name)
44+
rel = client.tables.get_relationship(schema_name)
4545
if rel:
4646
rel_id = rel.get("MetadataId")
4747
if rel_id:
48-
client.delete_relationship(rel_id)
48+
client.tables.delete_relationship(rel_id)
4949
print(f" (Cleaned up existing relationship: {schema_name})")
5050
return True
5151
return False
@@ -75,8 +75,8 @@ def cleanup_previous_run(client):
7575
# Delete tables
7676
for table_name in tables:
7777
try:
78-
if client.get_table_info(table_name):
79-
client.delete_table(table_name)
78+
if client.tables.get(table_name):
79+
client.tables.delete(table_name)
8080
print(f" (Cleaned up existing table: {table_name})")
8181
except Exception as e:
8282
print(f" [WARN] Could not delete table {table_name}: {e}")
@@ -159,7 +159,7 @@ def main():
159159
log_call("Creating 'new_Department' table")
160160

161161
dept_table = backoff(
162-
lambda: client.create_table(
162+
lambda: client.tables.create(
163163
"new_Department",
164164
{
165165
"new_DepartmentCode": "string",
@@ -173,7 +173,7 @@ def main():
173173
log_call("Creating 'new_Employee' table")
174174

175175
emp_table = backoff(
176-
lambda: client.create_table(
176+
lambda: client.tables.create(
177177
"new_Employee",
178178
{
179179
"new_EmployeeNumber": "string",
@@ -187,7 +187,7 @@ def main():
187187
log_call("Creating 'new_Project' table")
188188

189189
proj_table = backoff(
190-
lambda: client.create_table(
190+
lambda: client.tables.create(
191191
"new_Project",
192192
{
193193
"new_ProjectCode": "string",
@@ -228,7 +228,7 @@ def main():
228228

229229
# Create the relationship
230230
result = backoff(
231-
lambda: client.create_one_to_many_relationship(
231+
lambda: client.tables.create_one_to_many_relationship(
232232
lookup=lookup,
233233
relationship=relationship,
234234
)
@@ -252,7 +252,7 @@ def main():
252252
# Use the convenience method for simpler scenarios
253253
# An Employee has a Manager (who is a Contact in the system)
254254
result2 = backoff(
255-
lambda: client.create_lookup_field(
255+
lambda: client.tables.create_lookup_field(
256256
referencing_table=emp_table["table_logical_name"],
257257
lookup_field_name="new_ManagerId",
258258
referenced_table="contact",
@@ -285,7 +285,7 @@ def main():
285285
)
286286

287287
result3 = backoff(
288-
lambda: client.create_many_to_many_relationship(
288+
lambda: client.tables.create_many_to_many_relationship(
289289
relationship=m2m_relationship,
290290
)
291291
)
@@ -304,7 +304,7 @@ def main():
304304

305305
log_call("Retrieving 1:N relationship by schema name")
306306

307-
rel_metadata = client.get_relationship("new_Department_Employee")
307+
rel_metadata = client.tables.get_relationship("new_Department_Employee")
308308
if rel_metadata:
309309
print(f"[OK] Found relationship: {rel_metadata.get('SchemaName')}")
310310
print(f" Type: {rel_metadata.get('@odata.type')}")
@@ -315,7 +315,7 @@ def main():
315315

316316
log_call("Retrieving M:N relationship by schema name")
317317

318-
m2m_metadata = client.get_relationship("new_employee_project")
318+
m2m_metadata = client.tables.get_relationship("new_employee_project")
319319
if m2m_metadata:
320320
print(f"[OK] Found relationship: {m2m_metadata.get('SchemaName')}")
321321
print(f" Type: {m2m_metadata.get('@odata.type')}")
@@ -338,21 +338,21 @@ def main():
338338
log_call("Deleting relationships")
339339
try:
340340
if rel_id_1:
341-
backoff(lambda: client.delete_relationship(rel_id_1))
341+
backoff(lambda: client.tables.delete_relationship(rel_id_1))
342342
print(f" [OK] Deleted relationship: new_Department_Employee")
343343
except Exception as e:
344344
print(f" [WARN] Error deleting relationship 1: {e}")
345345

346346
try:
347347
if rel_id_2:
348-
backoff(lambda: client.delete_relationship(rel_id_2))
348+
backoff(lambda: client.tables.delete_relationship(rel_id_2))
349349
print(f" [OK] Deleted relationship: contact->employee (Manager)")
350350
except Exception as e:
351351
print(f" [WARN] Error deleting relationship 2: {e}")
352352

353353
try:
354354
if rel_id_3:
355-
backoff(lambda: client.delete_relationship(rel_id_3))
355+
backoff(lambda: client.tables.delete_relationship(rel_id_3))
356356
print(f" [OK] Deleted relationship: new_employee_project")
357357
except Exception as e:
358358
print(f" [WARN] Error deleting relationship 3: {e}")
@@ -361,7 +361,7 @@ def main():
361361
log_call("Deleting tables")
362362
for table_name in ["new_Employee", "new_Department", "new_Project"]:
363363
try:
364-
backoff(lambda name=table_name: client.delete_table(name))
364+
backoff(lambda name=table_name: client.tables.delete(name))
365365
print(f" [OK] Deleted table: {table_name}")
366366
except Exception as e:
367367
print(f" [WARN] Error deleting {table_name}: {e}")

0 commit comments

Comments
 (0)