DataFrameOperations Class
Namespace for pandas DataFrame CRUD operations.
Accessed via client.dataframe. Provides DataFrame-oriented wrappers
around the record-level CRUD operations.
Example:
import pandas as pd
client = DataverseClient(base_url, credential)
# Query records as a DataFrame
df = client.dataframe.get("account", select=["name"], top=100)
# Create records from a DataFrame
new_df = pd.DataFrame([{"name": "Contoso"}, {"name": "Fabrikam"}])
new_df["accountid"] = client.dataframe.create("account", new_df)
# Update records
new_df["telephone1"] = ["555-0100", "555-0200"]
client.dataframe.update("account", new_df, id_column="accountid")
# Delete records
client.dataframe.delete("account", new_df["accountid"])
Constructor
DataFrameOperations(client: DataverseClient)
Parameters
| Name | Description |
|---|---|
|
client
Required
|
The parent DataverseClient instance. |
Methods
| create |
Create records from a pandas DataFrame. Tip All rows are sent in a single CreateMultiple request. For very large DataFrames, consider splitting into smaller batches to avoid request timeouts. |
| delete |
Delete records by passing a pandas Series of GUIDs. |
| get |
Fetch records and return as a single pandas DataFrame. When Tip For large tables, use top or filter to limit the result set. |
| sql |
Execute a SQL query and return the results as a pandas DataFrame. Delegates to sql and converts the list of records into a single DataFrame. |
| update |
Update records from a pandas DataFrame. Each row in the DataFrame represents an update. The Tip All rows are sent in a single UpdateMultiple request (or a single PATCH for one row). For very large DataFrames, consider splitting into smaller batches to avoid request timeouts. |
create
Create records from a pandas DataFrame.
Tip
All rows are sent in a single CreateMultiple request. For very
large DataFrames, consider splitting into smaller batches to avoid
request timeouts.
create(table: str, records: DataFrame) -> Series
Parameters
| Name | Description |
|---|---|
|
table
Required
|
Schema name of the table (e.g. |
|
records
Required
|
DataFrame where each row is a record to create. |
Returns
| Type | Description |
|---|---|
|
Series of created record GUIDs, aligned with the input DataFrame index. |
Exceptions
| Type | Description |
|---|---|
|
If |
|
|
If |
Examples
Create records from a DataFrame:
import pandas as pd
df = pd.DataFrame([
{"name": "Contoso", "telephone1": "555-0100"},
{"name": "Fabrikam", "telephone1": "555-0200"},
])
df["accountid"] = client.dataframe.create("account", df)
delete
Delete records by passing a pandas Series of GUIDs.
delete(table: str, ids: Series, use_bulk_delete: bool = True) -> str | None
Parameters
| Name | Description |
|---|---|
|
table
Required
|
Schema name of the table (e.g. |
|
ids
Required
|
Series of record GUIDs to delete. |
|
use_bulk_delete
|
When Default value: True
|
Returns
| Type | Description |
|---|---|
|
str,
|
BulkDelete job ID when deleting multiple records via BulkDelete;
|
Exceptions
| Type | Description |
|---|---|
|
If |
|
|
If |
Examples
Delete records using a Series:
import pandas as pd
ids = pd.Series(["guid-1", "guid-2", "guid-3"])
client.dataframe.delete("account", ids)
get
Fetch records and return as a single pandas DataFrame.
When record_id is provided, returns a single-row DataFrame.
When record_id is None, internally iterates all pages and returns one
consolidated DataFrame.
Tip
For large tables, use top or filter to limit the result set.
get(table: str, record_id: str | None = None, select: List[str] | None = None, filter: str | None = None, orderby: List[str] | None = None, top: int | None = None, expand: List[str] | None = None, page_size: int | None = None, count: bool = False, include_annotations: str | None = None) -> DataFrame
Parameters
| Name | Description |
|---|---|
|
table
Required
|
Schema name of the table (e.g. |
|
record_id
|
Optional GUID to fetch a specific record. If None, queries multiple records. Default value: None
|
|
select
|
Optional list of attribute logical names to retrieve. Default value: None
|
|
filter
|
Optional OData filter string. Column names must use exact lowercase logical names. Default value: None
|
|
orderby
|
Optional list of attributes to sort by. Default value: None
|
|
top
|
Optional maximum number of records to return. Default value: None
|
|
expand
|
Optional list of navigation properties to expand (case-sensitive). Default value: None
|
|
page_size
|
Optional number of records per page for pagination. Default value: None
|
|
count
|
If Default value: False
|
|
include_annotations
|
OData annotation pattern for the
Default value: None
|
Returns
| Type | Description |
|---|---|
|
DataFrame containing all matching records. Returns an empty DataFrame when no records match. |
Exceptions
| Type | Description |
|---|---|
|
If |
Examples
Fetch a single record as a DataFrame:
df = client.dataframe.get("account", record_id=account_id, select=["name", "telephone1"])
print(df)
Query with filtering:
df = client.dataframe.get("account", filter="statecode eq 0", select=["name"])
print(f"Got {len(df)} active accounts")
Limit result size:
df = client.dataframe.get("account", select=["name"], top=100)
sql
Execute a SQL query and return the results as a pandas DataFrame.
Delegates to sql and converts the list of records into a single DataFrame.
sql(sql: str) -> DataFrame
Parameters
| Name | Description |
|---|---|
|
sql
Required
|
Supported SQL SELECT statement. |
Returns
| Type | Description |
|---|---|
|
DataFrame containing all result rows. Returns an empty DataFrame when no rows match. |
Exceptions
| Type | Description |
|---|---|
|
If |
Examples
SQL query to DataFrame:
df = client.dataframe.sql(
"SELECT TOP 100 name, revenue FROM account "
"WHERE statecode = 0 ORDER BY revenue"
)
print(f"Got {len(df)} rows")
print(df.head())
Aggregate query to DataFrame:
df = client.dataframe.sql(
"SELECT a.name, COUNT(c.contactid) as cnt "
"FROM account a "
"JOIN contact c ON a.accountid = c.parentcustomerid "
"GROUP BY a.name"
)
update
Update records from a pandas DataFrame.
Each row in the DataFrame represents an update. The id_column specifies which
column contains the record GUIDs.
Tip
All rows are sent in a single UpdateMultiple request (or a
single PATCH for one row). For very large DataFrames, consider
splitting into smaller batches to avoid request timeouts.
update(table: str, changes: DataFrame, id_column: str, clear_nulls: bool = False) -> None
Parameters
| Name | Description |
|---|---|
|
table
Required
|
Schema name of the table (e.g. |
|
changes
Required
|
DataFrame where each row contains a record GUID and the fields to update. |
|
id_column
Required
|
Name of the DataFrame column containing record GUIDs. |
|
clear_nulls
|
When Default value: False
|
Exceptions
| Type | Description |
|---|---|
|
If |
|
|
If |
Examples
Update records with different values per row:
import pandas as pd
df = pd.DataFrame([
{"accountid": "guid-1", "telephone1": "555-0100"},
{"accountid": "guid-2", "telephone1": "555-0200"},
])
client.dataframe.update("account", df, id_column="accountid")
Broadcast the same change to all records:
df = pd.DataFrame({"accountid": ["guid-1", "guid-2", "guid-3"]})
df["websiteurl"] = "https://example.com"
client.dataframe.update("account", df, id_column="accountid")
Clear a field by setting clear_nulls=True:
df = pd.DataFrame([{"accountid": "guid-1", "websiteurl": None}])
client.dataframe.update("account", df, id_column="accountid", clear_nulls=True)