# Querying SAP entities

Server-side filtering, field selection, related entities and paging through large SAP result sets.

SAP systems perform filtering, sorting and field selection on the server - the client specifies its criteria in query options and only the matching data comes back. SAP connections run on the OData implementation, so everything in the [OData query options](https://zato.io/docs/dev/odata/query/index.html) chapter applies to them - this page shows the options in SAP terms.

## Keyword arguments {#keyword-arguments}

Each query option is a keyword argument to .read, .iter and .get, without the dollar prefix:

```python
conn = self.sap['SAP.Sample']

partners = conn.read('A_BusinessPartner',
    filter="CityName eq 'London' and BusinessPartnerCategory eq '1'",
    select='BusinessPartner,BusinessPartnerName,CityName',
    orderby='BusinessPartnerName desc',
    top=20,
    skip=40,
)
```

The client encodes each option correctly for the connection's OData version - for instance, inline counts are requested with `$inlinecount=allpages` in V2 services and `$count=true` in V4 ones.

## Selecting fields {#selecting-fields}

SAP entities are wide - a business partner has dozens of properties. The select option keeps the payloads small by naming only the fields the service needs:

```python
partners = conn.read('A_BusinessPartner',
    select='BusinessPartner,BusinessPartnerName',
)
```

## Related entities {#related-entities}

Navigation properties - order items, partner addresses, employment records - come inline with the expand option, saving one round trip per relation:

```python
orders = conn.read('A_SalesOrder',
    filter="SoldToParty eq '1000001'",
    expand='to_Item',
)
```

## Paging {#paging}

.read returns one page and .iter follows the server's paging links until the whole result set is exhausted - Gateway's skiptokens and SuccessFactors' `__next` links alike:

```python
for partner in conn.iter('A_BusinessPartner', filter="Country eq 'DE'"):
    self.logger.info('Received -> %s', partner['BusinessPartner'])
```

A connection-wide page size can be set in the connection's form - it is sent as `Prefer: odata.maxpagesize` and the server keeps each page at or below it.

## SAP-specific parameters {#sap-specific-parameters}

Parameters outside of the OData standard, such as `sap-client` or `sap-language`, go through the custom option as they are:

```python
partners = conn.read('A_BusinessPartner',
    top=10,
    custom={'sap-client': '100', 'sap-language': 'EN'},
)
```

## Learn more {#learn-more}

- [SAP integrations](https://zato.io/docs/dev/sap/) - Business entities as Python dicts, over OData V2 and V4
- [S/4HANA and ECC](https://zato.io/docs/dev/sap/s4hana/) - Gateway services, their entity sets and what they expect
- [SuccessFactors](https://zato.io/docs/dev/sap/success-factors/) - The OData V2 API, its authentication and its quirks
- [SAP security](https://zato.io/docs/dev/sap/security/) - Basic Auth, API keys, bearer tokens and OAuth2 client credentials
- [SAP in enmasse](https://zato.io/docs/dev/sap/enmasse/) - Connections as YAML, with secrets read from the environment
