Skip to content

Commit 1cde7e8

Browse files
author
Saurabh Badenkal
committed
Validate query params with record_id, normalize datetime/np.datetime64, use context manager in example
1 parent 38c1297 commit 1cde7e8

5 files changed

Lines changed: 52 additions & 1 deletion

File tree

examples/advanced/dataframe_operations.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@ def main():
3030

3131
print("[INFO] Authenticating via browser...")
3232
credential = InteractiveBrowserCredential()
33-
client = DataverseClient(base_url, credential)
3433

34+
with DataverseClient(base_url, credential) as client:
35+
_run_walkthrough(client)
36+
37+
38+
def _run_walkthrough(client):
3539
table = input("Enter table schema name to use [default: account]: ").strip() or "account"
3640
print(f"[INFO] Using table: {table}")
3741

src/PowerPlatform/Dataverse/operations/dataframe.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ def get(
110110
df = client.dataframe.get("account", select=["name"], top=100)
111111
"""
112112
if record_id is not None:
113+
if any(p is not None for p in (filter, orderby, top, expand, page_size)):
114+
raise ValueError(
115+
"Cannot specify query parameters (filter, orderby, top, "
116+
"expand, page_size) when fetching a single record by ID"
117+
)
113118
result = self._client.records.get(
114119
table,
115120
record_id,

src/PowerPlatform/Dataverse/utils/_pandas.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
from __future__ import annotations
77

8+
import datetime
89
from typing import Any, Dict, List
910

1011
import numpy as np
@@ -19,6 +20,10 @@ def _normalize_scalar(v: Any) -> Any:
1920
"""
2021
if isinstance(v, pd.Timestamp):
2122
return v.isoformat()
23+
if isinstance(v, (datetime.datetime, datetime.date)):
24+
return v.isoformat()
25+
if isinstance(v, np.datetime64):
26+
return pd.Timestamp(v).isoformat()
2227
if isinstance(v, np.integer):
2328
return int(v)
2429
if isinstance(v, np.floating):

tests/unit/test_dataframe_operations.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,18 @@ def test_get_passes_all_params(self):
175175
page_size=25,
176176
)
177177

178+
def test_get_record_id_with_query_params_raises(self):
179+
"""ValueError raised when record_id is provided with query params."""
180+
with self.assertRaises(ValueError) as ctx:
181+
self.client.dataframe.get("account", record_id="guid-1", filter="name eq 'X'")
182+
self.assertIn("Cannot specify query parameters", str(ctx.exception))
183+
184+
def test_get_record_id_with_top_raises(self):
185+
"""ValueError raised when record_id is provided with top."""
186+
with self.assertRaises(ValueError) as ctx:
187+
self.client.dataframe.get("account", record_id="guid-1", top=10)
188+
self.assertIn("Cannot specify query parameters", str(ctx.exception))
189+
178190

179191
class TestDataFrameCreate(unittest.TestCase):
180192
"""Tests for client.dataframe.create()."""

tests/unit/test_pandas_helpers.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,31 @@ def test_numpy_float32(self):
8585
self.assertIsInstance(result, float)
8686
self.assertAlmostEqual(result, 2.5, places=5)
8787

88+
def test_python_datetime(self):
89+
"""datetime.datetime is converted to ISO 8601 string."""
90+
import datetime
91+
92+
dt = datetime.datetime(2024, 6, 15, 10, 30, 0)
93+
result = _normalize_scalar(dt)
94+
self.assertIsInstance(result, str)
95+
self.assertEqual(result, "2024-06-15T10:30:00")
96+
97+
def test_python_date(self):
98+
"""datetime.date is converted to ISO 8601 string."""
99+
import datetime
100+
101+
d = datetime.date(2024, 6, 15)
102+
result = _normalize_scalar(d)
103+
self.assertIsInstance(result, str)
104+
self.assertEqual(result, "2024-06-15")
105+
106+
def test_numpy_datetime64(self):
107+
"""np.datetime64 is converted to ISO 8601 string."""
108+
dt = np.datetime64("2024-06-15T10:30:00")
109+
result = _normalize_scalar(dt)
110+
self.assertIsInstance(result, str)
111+
self.assertIn("2024-06-15T10:30:00", result)
112+
88113

89114
class TestDataframeToRecords(unittest.TestCase):
90115
"""Unit tests for dataframe_to_records()."""

0 commit comments

Comments
 (0)