SAP MM Purchasing data model
Third-normal-form mirror of the SAP MM procure-to-pay tables as they land from the source ERP. Each SAP table becomes its own entity with a warehouse surrogate key plus the genuine SAP business key(s), and child item/schedule/history tables reference their header/master tables via foreign keys. Vendor name, address and tax identifiers are PII-masked under GDPR.
Normalized replica of SAP ECC/S4HANA Materials Management procurement source tables for a warehouse staging/replication layer: purchase order header (EKKO), item (EKPO), schedule (EKET) and PO history (EKBE); purchase requisitions (EBAN); goods movements (MKPF/MSEG); and purchasing info records (EINA/EINE) — keyed by the real SAP business keys (ebeln, ebelp, etenr, banfn, mblnr) and anchored to vendor (LFA1), plant (T001W), purchasing org and material (MARA) check/master tables. It is a normalized (3NF) relational model that mirrors the source system, suited to operational databases and to landing source data faithfully.
- 14
- tables
- 136
- columns
- 18
- relationships
- 7
- PII columns
Opening the template creates a project with the ERD, platform-native DDL, a dbt project and documentation already generated (recommended platform: PostgreSQL). Edit it in plain English or on the canvas, then ship it to any supported warehouse.
Subject areas
Design decisions
Header/item/schedule normalization mirrors SAP MM
SAP MM stores a purchase order as EKKO (header) → EKPO (item) → EKET (schedule line); replicating that hierarchy 1:1 keeps the staging layer lossless and reconcilable against the source EKKO/EKPO/EKET tables.
Separate PO history and goods movements
Goods receipts and invoice receipts are posted as material documents (MKPF/MSEG) and summarized into PO history (EKBE); keeping them as their own entities preserves the GR/IR audit trail SAP records per PO item.
Info records split into general and org-level data
SAP separates purchasing info record general data (EINA) from purchasing organization data (EINE) because price/lead-time vary by purchasing org; the split avoids repeating vendor/material keys across org rows.
Check tables modeled as lookups
Purchasing org, plant (T001W), vendor (LFA1) and material (MARA) are slow SAP check/master tables; modeling them as lookups without an audit trail keeps reference data clean and avoids re-keying every transaction row.
Tables in the SAP MM Purchasing model
Every table with its grain, columns, types and keys. PK marks a primary key, BK a business key and PII a column classified as personal data, which gets a masking strategy by default.
Tables (10)
purchase_req_header
Grain: one row per purchase requisition (banfn)
SAP EBAN (header-level attributes) — purchase requisition.
| Column | Type | Keys |
|---|---|---|
| purchase_req_header_key | bigint | PK |
| banfn | varchar | BK |
| bsart | varchar | |
| ernam | varchar | PII |
| erdat | date |
purchase_req_item
Grain: one row per purchase requisition item (banfn, bnfpo)
SAP EBAN — purchase requisition item.
| Column | Type | Keys |
|---|---|---|
| purchase_req_item_key | bigint | PK |
| purchase_req_header_key | bigint | |
| material_key | bigint | |
| plant_key | bigint | |
| banfn | varchar | BK |
| bnfpo | varchar | BK |
| matnr | varchar | |
| werks | varchar | |
| menge | decimal | |
| meins | varchar | |
| lfdat | date | |
| preis | decimal | |
| frgkz | varchar |
po_header
Grain: one row per purchase order header (ebeln)
SAP EKKO — purchasing document header.
| Column | Type | Keys |
|---|---|---|
| po_header_key | bigint | PK |
| vendor_key | bigint | |
| purchasing_org_key | bigint | |
| ebeln | varchar | BK |
| bsart | varchar | |
| bstyp | varchar | |
| lifnr | varchar | |
| ekorg | varchar | |
| ekgrp | varchar | |
| bukrs | varchar | |
| waers | varchar | |
| bedat | date | |
| ernam | varchar | PII |
po_item
Grain: one row per purchase order item (ebeln, ebelp)
SAP EKPO — purchasing document item.
| Column | Type | Keys |
|---|---|---|
| po_item_key | bigint | PK |
| po_header_key | bigint | |
| material_key | bigint | |
| plant_key | bigint | |
| ebeln | varchar | BK |
| ebelp | varchar | BK |
| matnr | varchar | |
| txz01 | varchar | |
| werks | varchar | |
| lgort | varchar | |
| menge | decimal | |
| meins | varchar | |
| netpr | decimal | |
| netwr | decimal | |
| mwskz | varchar | |
| loekz | varchar |
po_schedule
Grain: one row per PO delivery schedule line (ebeln, ebelp, etenr)
SAP EKET — scheduling agreement schedule lines.
| Column | Type | Keys |
|---|---|---|
| po_schedule_key | bigint | PK |
| po_item_key | bigint | |
| ebeln | varchar | BK |
| ebelp | varchar | BK |
| etenr | varchar | BK |
| eindt | date | |
| menge | decimal | |
| wemng | decimal | |
| dabmg | decimal |
po_history
Grain: one row per PO history record (ebeln, ebelp, zekkn, vgabe, gjahr, belnr, buzei)
SAP EKBE — purchase order history.
| Column | Type | Keys |
|---|---|---|
| po_history_key | bigint | PK |
| po_item_key | bigint | |
| ebeln | varchar | BK |
| ebelp | varchar | BK |
| vgabe | varchar | BK |
| gjahr | varchar | BK |
| belnr | varchar | BK |
| buzei | varchar | BK |
| bewtp | varchar | |
| menge | decimal | |
| dmbtr | decimal | |
| shkzg | varchar | |
| budat | date |
goods_movement_header
Grain: one row per material document header (mblnr, mjahr)
SAP MKPF — material document header.
| Column | Type | Keys |
|---|---|---|
| goods_movement_header_key | bigint | PK |
| mblnr | varchar | BK |
| mjahr | varchar | BK |
| bldat | date | |
| budat | date | |
| usnam | varchar | PII |
| blart | varchar |
goods_movement
Grain: one row per material document item (mblnr, mjahr, zeile)
SAP MSEG — material document segment.
| Column | Type | Keys |
|---|---|---|
| goods_movement_key | bigint | PK |
| goods_movement_header_key | bigint | |
| material_key | bigint | |
| plant_key | bigint | |
| po_item_key | bigint | |
| mblnr | varchar | BK |
| mjahr | varchar | BK |
| zeile | varchar | BK |
| bwart | varchar | |
| matnr | varchar | |
| werks | varchar | |
| lgort | varchar | |
| menge | decimal | |
| meins | varchar | |
| dmbtr | decimal | |
| shkzg | varchar | |
| ebeln | varchar | |
| ebelp | varchar |
info_record
Grain: one row per purchasing info record general data (infnr)
SAP EINA — purchasing info record general data.
| Column | Type | Keys |
|---|---|---|
| info_record_key | bigint | PK |
| vendor_key | bigint | |
| material_key | bigint | |
| infnr | varchar | BK |
| lifnr | varchar | |
| matnr | varchar | |
| matkl | varchar | |
| loekz | varchar |
info_record_org
Grain: one row per info record purchasing org data (infnr, ekorg, esokz, werks)
SAP EINE — purchasing info record purchasing organization data.
| Column | Type | Keys |
|---|---|---|
| info_record_org_key | bigint | PK |
| info_record_key | bigint | |
| purchasing_org_key | bigint | |
| infnr | varchar | BK |
| ekorg | varchar | BK |
| esokz | varchar | BK |
| netpr | decimal | |
| waers | varchar | |
| aplfz | decimal | |
| ekgrp | varchar |
Lookup tables (4)
purchasing_org
Grain: one row per purchasing organization
SAP T024E — purchasing organization check table.
| Column | Type | Keys |
|---|---|---|
| purchasing_org_key | bigint | PK |
| ekorg | varchar | BK |
| ekotx | varchar | |
| bukrs | varchar |
plant
Grain: one row per plant / receiving location
SAP T001W — plant/branch check table.
| Column | Type | Keys |
|---|---|---|
| plant_key | bigint | PK |
| werks | varchar | BK |
| name1 | varchar | |
| land1 | varchar | |
| regio | varchar | |
| bukrs | varchar |
material
Grain: one row per material master general record
SAP MARA — material master (general), referenced as a lookup here.
| Column | Type | Keys |
|---|---|---|
| material_key | bigint | PK |
| matnr | varchar | BK |
| mtart | varchar | |
| matkl | varchar | |
| meins | varchar | |
| maktx | varchar |
vendor
Grain: one row per vendor master general record
SAP LFA1 — vendor master (general), referenced as a lookup here.
| Column | Type | Keys |
|---|---|---|
| vendor_key | bigint | PK |
| lifnr | varchar | BK |
| name1 | varchar | PII |
| land1 | varchar | |
| ort01 | varchar | PII |
| pstlz | varchar | PII |
| stcd1 | varchar | PII |
| ktokk | varchar |
Relationships
Each relationship is a foreign key on the first table referencing the second.
- purchase_req_item.purchase_req_header_key → purchase_req_header (many-to-one)
- purchase_req_item.material_key → material (many-to-one)
- purchase_req_item.plant_key → plant (many-to-one)
- po_header.vendor_key → vendor (many-to-one)
- po_header.purchasing_org_key → purchasing_org (many-to-one)
- po_item.po_header_key → po_header (many-to-one)
- po_item.material_key → material (many-to-one)
- po_item.plant_key → plant (many-to-one)
- po_schedule.po_item_key → po_item (many-to-one)
- po_history.po_item_key → po_item (many-to-one)
- goods_movement.goods_movement_header_key → goods_movement_header (many-to-one)
- goods_movement.material_key → material (many-to-one)
- goods_movement.plant_key → plant (many-to-one)
- goods_movement.po_item_key → po_item (many-to-one)
- info_record.vendor_key → vendor (many-to-one)
- info_record.material_key → material (many-to-one)
- info_record_org.info_record_key → info_record (many-to-one)
- info_record_org.purchasing_org_key → purchasing_org (many-to-one)
Related templates
All templates →From requirements to AI-ready context, in one platform.
Describe your business in a conversation, start from a template or connect your own database. Your first model is ready in minutes.
