SPS V4 · Data contract

Read-only DB access for the Data Lake gold pull

A read-only Postgres view schema, pbi_v1, on the SPS V4 production database. Connect over JDBC as pbi_reader, read the seven pbi_v1.* views, write to gold. Everything you need to build against is on this page.

01 Connect

Server
sps-v4-prod-db.postgres.database.azure.com
Port
5432
Database
sps_v4
User
pbi_reader
Password
sent to you separately by Vilius
SSL
required  sslmode=require
Schema
pbi_v1  read only

JDBC URL

jdbc:postgresql://sps-v4-prod-db.postgres.database.azure.com:5432/sps_v4?sslmode=require

Databricks (the Postgres driver is bundled — no extra install)

url = "jdbc:postgresql://sps-v4-prod-db.postgres.database.azure.com:5432/sps_v4?sslmode=require"
props = {
    "user": "pbi_reader",
    "password": dbutils.secrets.get(scope="...", key="pbi_reader_pw"),
    "driver": "org.postgresql.Driver",
}
df = spark.read.jdbc(url=url, table="pbi_v1.v_projects", properties=props)
Network prerequisite — set this up before your first run. The prod DB firewall allow-lists by IP, and a Spark read.jdbc connects from every cluster node — the driver and each executor — not a single address. Workspace adb-8019543586872068 currently egresses via Azure default-outbound, so each node gets its own ephemeral public IP; allow-listing them one by one can't hold across scale/recycle. Attach a NAT gateway to the workspace subnets so all nodes share one stable egress IP, then send that IP to Vilius to allow-list. Until that's in place the connection times out on the executors even though the driver reaches the DB. The NAT gateway is your side; opening the firewall to that one IP is Vilius's.

02 The contract

03 Column dictionary

Seven views. project_id is text and joins across all of them. Types are the Postgres types you'll receive.

grain composite key / one row per… confirm unit/scale with Vilius

pbi_v1.v_projects

One row per non-archived project. Master fields as seen on the STATUSAS / PROJEKTAI tabs. grain: project_id

ColumnTypeMeaning
project_idtextPrimary key. Joins to every other view.
codetextShort project code.
nametextDisplay name.
full_nametextLong / legal name (nullable).
typetextSingle-letter type code (nullable).
stagetextStage code (nullable). Labels live in reference.project_stages, see §06.
countrytext2-letter country code (nullable).
start_datedateProject start.
agreed_end_datedateAgreed end date.
contract_end_datedateContractual end date.
financial_close_datedateFinancial close (nullable).
contract_revenuenumeric(14,2)Contract revenue, EUR.
contract_costsnumeric(14,2)Contract costs, EUR.
contract_hoursnumeric(10,2)Contracted hours.
total_volume_m2numeric(12,3)Total work volume, m² (nullable — set on few projects).
materials_not_neededbooleanProject has no materials scope.
pv_nametextProject manager(s), comma-joined, name only. Multiple possible.
av_nametextDeputy(ies), comma-joined, name only.
ps_nametextSite manager(s), comma-joined, name only.
updated_attimestamptzReal row watermark. Last change to the project row.

pbi_v1.v_project_status_weekly

One row per project per ISO week — the full weekly STATUSAS history. grain: project_id, year, week_number

ColumnTypeMeaning
project_idtextFK → v_projects.
yearintISO year.
week_numberintISO week, 1–53.
iso_week_keytextConvenience join key, format YYYY-Www (e.g. 2026-W28). ISO year+week.
expected_end_datedateExpected end as of this week (nullable).
workers_hotremaintHotrema headcount this week (nullable).
workers_otherintSub-contractor headcount (nullable).
sukaupimainumeric(14,2)Accruals. EUR
atsargos_visonumeric(14,2)Inventory, total. EUR
atsargos_30dnumeric(14,2)Inventory, ≤30 days. EUR
atsargos_90dnumeric(14,2)Inventory, ≤90 days. EUR
buffer_consumed_pctnumeric(8,4)Buffer consumed, percent value — can exceed 100. ⚑ scale
work_done_pctnumeric(8,4)Work completed, percent value. ⚑ scale
hours_done_cumnumeric(10,2)Cumulative hours worked to date.
submitted_attimestamptzReal row watermark. When this week was submitted (nullable if never submitted).

pbi_v1.v_latest_project_status_weekly

The single most-recent weekly row per project. Same columns as above, plus one. grain: project_id

ColumnTypeMeaning
…all v_project_status_weekly columns…Identical shape, latest (year, week_number) per project.
is_current_weekbooleantrue when that latest row is the ISO current week relative to when you query. Computed at read time, not stored.

pbi_v1.v_project_financials

One row per project per month. grain: project_id, month

ColumnTypeMeaning
project_idtextFK → v_projects.
monthdateMonth-end date (canonical last-day-of-month). Use as your month grain.
rev_primarynumeric(14,2)Primary revenue, EUR.
rev_additionalnumeric(14,2)Additional revenue, EUR.
rev_reklamacijosnumeric(14,2)Reclamation/warranty revenue, EUR.
costs_primarynumeric(14,2)Primary costs, EUR.
costs_additionalnumeric(14,2)Additional costs, EUR.
hours_primarynumeric(10,2)Primary hours.
hours_additionalnumeric(10,2)Additional hours.
actual_workersintActual headcount for the month (nullable).
planned_workersnumeric(10,2)Planned headcount (fractional allowed, nullable).

pbi_v1.v_project_materials_monthly

One row per project per material per month. grain: project_id, material_name, month

ColumnTypeMeaning
project_idtextFK → v_projects.
material_typetextCategory label. Admin-definable — do not hardcode; new/renamed values appear over time.
material_nametextCatalog material name.
unittextUnit of qty (e.g. m², m). Key any KPI roll-ups off this, not off material_type.
monthdateMonth-end date.
qtynumeric(12,3)Quantity for the month, in unit.

pbi_v1.v_project_work_volumes

One row per project per ISO week. grain: project_id, year, week_number

ColumnTypeMeaning
project_idtextFK → v_projects.
yearintISO year.
week_numberintISO week, 1–53.
iso_week_keytextYYYY-Www.
plannednumeric(12,3)Planned volume. m²
actualnumeric(12,3)Actual volume. m²

pbi_v1.v_project_critical_activities

One row per active critical activity per project (current state, archived rows excluded). grain: project_id, sequence

ColumnTypeMeaning
project_idtextFK → v_projects.
sequenceintOrdering within the project.
tasktextActivity description.
basistextBasis / reference (nullable).
deadlinedateTarget date (nullable).
donetextISO completion date as text when done, else null. Not a boolean.
is_donebooleanConvenience flag = done IS NOT NULL.
owner_nametextOwner display name, name only (nullable).

04 Sample query

Latest weekly status across all active projects — mirrors the STATUSAS browse screen.

SELECT p.code, p.name, p.stage, p.country, p.pv_name,
       sw.expected_end_date, sw.workers_hotrema, sw.workers_other,
       sw.sukaupimai, sw.atsargos_viso, sw.atsargos_30d, sw.atsargos_90d,
       sw.year, sw.week_number, sw.is_current_week
FROM pbi_v1.v_projects p
JOIN pbi_v1.v_latest_project_status_weekly sw ON sw.project_id = p.project_id
ORDER BY p.code;

05 Things that bite

06 Load & refresh

07 Changes & contact

One rule covers all of it: read pbi_v1.*, treat columns as add-only, and anything you need beyond the seven views is a short conversation with Vilius — not a workaround against the base tables (they're not reachable anyway).