次の方法で共有


データの操作 (プレビュー)

[この記事はプレリリース ドキュメントであり、変更されることがあります。]

この記事では、SDK を使用して Dataverse のデータとメタデータを操作するコード例をいくつか示します。 この記事に進む前に、まず「 はじめに (プレビュー)」 を読んでください。

基本操作

アカウント テーブルで動作するコード例を次に示します。

from azure.identity import InteractiveBrowserCredential
from PowerPlatform.Dataverse.client import DataverseClient

base_url = "https://<myorg>.crm.dynamics.com"
client = DataverseClient(base_url=base_url, credential=InteractiveBrowserCredential())

# Create an account and set some properties (returns list[str] of new GUIDs)
account_id = client.create("account", {"name": "Acme, Inc.", "telephone1": "555-0100"})[0]

# Read an account 
account = client.get("account", account_id)

# Update an account (returns None)
client.update("account", account_id, {"telephone1": "555-0199"})

# Delete an account
client.delete("account", account_id)

一括操作

ここでは、一括更新を実行する例をいくつか示します。

# Bulk update (broadcast) – apply same patch to several IDs
ids = client.create("account", [
    {"name": "Contoso"},
    {"name": "Fabrikam"},
])
client.update("account", ids, {"telephone1": "555-0200"})  # broadcast patch

# Bulk update (1:1) – list of patches matches list of IDs
client.update("account", ids, [
    {"telephone1": "555-1200"},
    {"telephone1": "555-1300"},
])
print({"multi_update": "ok"})

ここでは、複数のアカウントを作成する例を示します。 create(logical_name, payloads)にペイロードの一覧を渡して、コレクション バインドMicrosoft.Dynamics.CRM.CreateMultipleアクションを呼び出します。 このメソッドは、作成されたレコード ID の list[str] を返します。

# Bulk create accounts (returns list of GUIDs)
payloads = [
    {"name": "Contoso"},
    {"name": "Fabrikam"},
    {"name": "Northwind"},
]
ids = client.create("account", payloads)
assert isinstance(ids, list) and all(isinstance(x, str) for x in ids)
print({"created_ids": ids})

一括操作に関する追加情報:

  • セマンティクスの一貫性を保つために None (単一の更新と同じ) を返します。
  • ブロードキャストとレコードごとの比較は、 changes パラメーターがディクショナリかリストかによって決まります。
  • UpdateMultiple アクション ターゲットを構築すると、主キー属性が自動的に挿入されます。
  • ペイロードが @odata.typeを省略すると、自動的にスタンプされます (キャッシュされた論理名参照)。
  • 応答には ID のみが含まれます。SDK はそれらの GUID 文字列を返します。
  • 単一レコード作成では、GUID の 1 要素リストが返されます。
  • @odata.typeのメタデータ検索は、エンティティ セット (メモリ内キャッシュ) ごとに 1 回実行されます。

ファイルのアップロード

アカウント レコードの "sample_filecolumn" という名前のファイル列に 'test.pdf' という名前の ファイル をアップロードする例をいくつか次に示します。 1 つ目の例は 128 MB 未満のファイル サイズに対し、2 番目の例は 128 MB を超えるファイル サイズです。

client.upload_file('account', record_id, 'sample_filecolumn', 'test.pdf')
client.upload_file('account', record_id, 'sample_filecolumn', 'test.pdf', mode='chunk', if_none_match=True)

ファイルのアップロードに関する追加情報:

  • upload_file は、ファイル サイズに基づいて使用する 3 つの方法のいずれかを選択します。 ファイル サイズが 128 MB 未満の場合、SDK は upload_file_smallを使用します。それ以外の場合、SDK は upload_file_chunk
  • upload_file_small は 1 つの Web API 呼び出しを行い、128 MB < ファイル サイズのみをサポートします。
  • upload_file_chunk PATCH と Content-Range を使用してファイルをアップロードします (Dataverse メッセージと比較して HTTP 標準に合わせて調整されます)。 1 という 2 つのステージで構成されます。 実際のアップロードに使用されるヘッダーを取得するための PATCH 要求、および 2。 実際のアップロード (チャンク単位)。 この関数は、最初のステージで返される OData x-ms-chunk-size を使用してチャンク サイズ (通常は 4 MB) を決定し、アップロードのメタデータとして Content-RangeContent-Length を使用します。 Web API 呼び出しの合計数は、チャンク数 + 1 です。

ページングで複数の項目を取得する

get関数を使用して、結果をページごとにストリーミングします。 合計結果を $top に上限を設定し、 page_size パラメーターを使用してページごとのサイズをヒントすることができます。 SDK は内部的に OData prefer ヘッダー odata.maxpagesizeを設定します。

pages = client.get(
    "account",
    select=["accountid", "name", "createdon"],
    orderby=["name asc"],
    top=10,          # stop after 10 total rows (optional)
    page_size=3,     # ask for ~3 per page (optional)
)

total = 0
for page in pages: # each page is a list[dict]
    print({"page_size": len(page), "sample": page[:2]})
    total += len(page)
print({"total_rows": total})

サポートされているパラメーターの一覧を次に示します。ただし、 logical_name以外はすべて省略可能です。

  • logical_name: str — 論理 (単数形) 名 (例: "account")。
  • select: list[str] |なし — 列 -> $select (コンマで結合)。
  • filter: str | None — OData $filter expression (for example, contains(name,'Acme') and statecode eq 0).
  • orderby: list[str] |None — 式の並べ替え -> $orderby (コンマ結合)。
  • top: int |なし — $top経由のグローバル上限 (最初の要求に適用され、サービスはページ間で適用されます)。
  • expand: list[str] | None — ナビゲーション拡張 -> $expand; 生の句を渡します (例: primarycontactid($select=fullname,emailaddress1))。
  • page_size: int |None — Prefer: odata.maxpagesize=<N> を使用したページ単位のヒント (保証されていません。最後のページが小さい場合があります)。

戻り値とセマンティクスの一覧を次に示します。

  • $select$filter$orderby$expand$top 、最初の要求の対応する OData クエリ オプションに直接マップされます。
  • $top 行の合計数を制限します。サービスはこれらの行を複数のページに分割することがあります。
  • page_size (Prefer: odata.maxpagesize) はヒントであり、サーバーは実際のページ境界を決定します。
  • 空でないページ (list[dict]) を生成するジェネレーターを返します。 空のページはスキップされます。
  • 生成された各リストは、Web API の値ページに対応します。
  • @odata.nextLinkが残っていない場合、またはサーバー側で$topが満たされた場合、イテレーションが停止します。
  • ジェネレーターはすべての結果を具体化するわけではありません。ページは遅延して取得されます。

サポートされているすべてのパラメーターと予想される応答を含む例を見てみましょう。

pages = client.get(
  "account",
  select=["accountid", "name", "createdon", "primarycontactid"],
  filter="contains(name,'Acme') and statecode eq 0",
  orderby=["name asc", "createdon desc"],
  top=5,
  expand=["primarycontactid($select=fullname,emailaddress1)"],
  page_size=2,
)

for page in pages:  # page is list[dict]
# Expected page shape (illustrative)
# [
# {
# "accountid": "00000000-0000-0000-0000-000000000001"
# "name": "Acme West"
# "createdon": "2025-08-01T12:34:56Z"
# "primarycontactid": {
# "contactid": "00000000-0000-0000-0000-0000000000aa"
# "fullname": "Jane Doe"
# "emailaddress1": "<jane@acme.com>"
# }
# "@odata.etag": "W/\"123456\""
# }
#
# ]
  print({"page_size": len(page)})

テーブル メタデータ

カスタム テーブルを操作するためのコード例を見てみましょう。

# Support enumerations with labels in different languages
class Status(IntEnum):
    Active = 1
    Inactive = 2
    Archived = 5
    __labels__ = {
        1033: {
            "Active": "Active",
            "Inactive": "Inactive",
            "Archived": "Archived",
        },
        1036: {
            "Active": "Actif",
            "Inactive": "Inactif",
            "Archived": "Archivé",
        }
    }

# Create a simple custom table and a few columns
info = client.create_table(
    "SampleItem",  # friendly name; defaults to SchemaName new_SampleItem
    {
        "code": "string",
        "count": "int",
        "amount": "decimal",
        "when": "datetime",
        "active": "bool",
        "status": Status,
    },
)

logical = info["entity_logical_name"]  # for example, "new_sampleitem"

# Create a record in the new table
# Set your publisher prefix (used when creating the table). If you used the default, it's "new".
prefix = "new"
name_attr = f"{prefix}_name"
id_attr = f"{logical}id"

rec_id = client.create(logical, {name_attr: "Sample A"})[0]

# Clean up
client.delete(logical, rec_id)          # delete record
client.delete_table("SampleItem")       # delete table (friendly name or explicit schema new_SampleItem)

カスタム テーブル メタデータの操作に関する追加情報:

  • create は常に GUID のリストを返します (単一入力の場合は length=1)。
  • updatedelete は、1 つのインターフェイスと複数のインターフェイスの両方の None を返します。
  • ペイロードの一覧を create に渡すと、一括作成がトリガーされ、ID の list[str] が返されます。
  • get では、レコード ID を使用した単一レコードの取得または結果セットのページングがサポートされています (列を制限する選択を優先します)。
  • レコード ID を受け取る CRUD メソッドの場合は、GUID 文字列 (ハイフネーション 36 文字) を渡します。 GUID を括弧で囲むことは受け入れられますが、必須ではありません。
  • SQL クエリは、 ?sql= パラメーターを使用してエンティティ セット エンドポイントに対して直接実行されます。 サポートされるサブセットのみ (単一の SELECT、省略可能な WHERE/TOP/ORDER BY、エイリアス)。 サポートされていないコンストラクトは、サービスによって拒否されます。

SDK での pandas の使用

PandasODataClient は、低レベルのクライアントを囲むシン ラッパーです。 すべてのメソッドは、エンティティ セット (複数形) 名ではなく、論理 (単数形) 名 (アカウント、new_sampleitemなど) を受け入れます。 ワークフローについては、'quickstart_pandas.py' という名前の SDK ソース リポジトリのDataFrameを参照してください。

こちらも参照ください