Skip to content

SAP OData

DataMaker speaks SAP OData natively. Point it at any V2 or V4 service — S/4HANA Cloud, S/4HANA on-prem via SAP Cloud Connector, BTP services, or a third-party SAP — and you get:

  • $metadata discovery: every entity set, every property, with types and Nullable flags.
  • Auto-CSRF: we fetch the x-csrf-token and replay it on every modifying request.
  • $filter queries: pull existing rows out for regression sets.
  • Direct POST: push generated data into entities, batch-aware.
  • No Z-customisations needed: we use the standard A2X services.

This is the same connection that powers the SAP regression and SAP TDMS alternative flows.

Create a SAP OData connection

Project → Connections → New → SAP OData. Fill in:

  • Name — e.g. S/4 Sandbox.

  • Service URL — root of the OData service. Examples:

    • S/4HANA Cloud: https://my-tenant.s4hana.cloud.sap/sap/opu/odata/sap/API_BUSINESS_PARTNER_SRV
    • On-prem via Cloud Connector: https://my-cc.example.com/sap/opu/odata/sap/API_BUSINESS_PARTNER_SRV
    • BTP destinations: paste the destination URL.
  • OData version — V2 or V4 (auto-detected from $metadata if you leave it on Auto).

  • Authbasic, oauth2-client-credentials, or destination (BTP).

Click Verify. We fetch $metadata, parse it, and list the entity sets we found.

What $metadata discovery gives you

After verification, the connection knows about every entity set:

Discovered 47 entity sets:
• A_BusinessPartner (28 properties)
• A_BPAddress (43 properties)
• A_BPBankDetails (16 properties)
• A_BPRole (5 properties)
...

Each property carries:

  • Its OData type (Edm.String, Edm.Decimal(15,2), etc.).
  • Nullable flag.
  • For string types, MaxLength.
  • For navigation properties, the related entity set.

The template builder uses this to validate generated data against the entity definition before you try to POST.

Auto-CSRF

OData V2/V4 modifying requests need a CSRF token. The flow is:

  1. GET / with X-CSRF-Token: Fetch → response carries a token in X-CSRF-Token.
  2. Subsequent POST/PUT/PATCH/DELETE requests include X-CSRF-Token: <that-token>.
  3. The token has the same lifetime as the auth session.

DataMaker handles all of this transparently. You never see a 403 because of CSRF.

Push a generated set into an entity

from datamaker import DataMaker
dm = DataMaker()
records = dm.generate(template_id="tmpl_business_partner", count=25)
dm.connection("conn_s4_sandbox").post(
entity="A_BusinessPartner",
rows=records,
)

Behind the scenes:

  • DataMaker fetches a CSRF token (or reuses a cached one).
  • For each row, makes a POST to /A_BusinessPartner.
  • Maps your template fields to OData properties (saved per template per connection).
  • Reports per-row status, including the BusinessPartner ID returned by SAP.

Fetch existing records ($filter)

For regression workflows, pull existing rows that match a filter:

records = dm.connection("conn_s4_sandbox").fetch(
entity="A_BusinessPartner",
filter="Country eq 'DE' and Industry eq 'HIGH_TECH'",
select=["BusinessPartner", "BusinessPartnerName", "TaxNumber1"],
top=200,
)

This produces a typed list of dicts that you can pass to other DataMaker actions — mask, save as a regression set, push to a different connection, etc.

Batch processing

For large pushes, OData V2 has $batch and V4 has $batch as well (different shapes). DataMaker can batch up to 100 rows per multipart request:

dm.connection("conn_s4_sandbox").post(
entity="A_BusinessPartner",
rows=records,
mode="batch",
batch_size=100,
)

CSRF, errors, and ChangeSet boundaries are handled per the OData spec.

Auth: BTP destinations

If you’re on SAP BTP, the cleanest auth path is a destination. In the connection form:

  • Pick Auth → BTP destination.
  • Provide the destination’s tenant URL and the destination name.
  • Authenticate via OAuth2 client credentials against the destination service.

DataMaker resolves the destination at use-time and uses whatever auth the destination is configured for (BasicAuthentication, OAuth2SAMLBearer, OAuth2UserTokenExchange…).

OData V4 vs V2

We handle both. Notable differences our connection abstracts away:

  • V2 uses $inlinecount=allpages, V4 uses $count=true.
  • V2 wraps responses in d.results, V4 uses value.
  • Date/datetime types differ (Edm.DateTime vs Edm.DateTimeOffset).

In your template, just pick “Date” — DataMaker emits the right format on the wire.

Troubleshooting

  • 403 CSRF token validation failed → the connection’s session expired between fetch and POST. We’ll retry; if it persists, check your auth.
  • 400 Property X is required → your template is missing a non-nullable property. Open the entity in the metadata view and look for Nullable=false properties without defaults.
  • 500 Business Partner type ... not allowed → SAP-side validation; this isn’t a DataMaker bug. Check your BusinessPartnerCategory and BPRole values.

For more, see Troubleshooting → CSRF & auth.