SAP-samples/hana-hdbext-promisfied-example
Promise-based wrappers around the SAP HANASAP HANASAP’s relational database platform, which stores application data and executes SQL and SQLScript in the database, available on-premise and as the managed service SAP HANA Cloud.sap official, btp client libraries for Node.jsNode.jsA cross-platform JavaScript runtime that servers, command line tools and scripts written in JavaScript are run with. For the things here, the prerequisite a repository names when its build is a set of npm scripts., Go and Python, replacing nested callbacks with a single async call.
The standard @sap/hdbext client chains a callback through prepare, then exec, then a callback for the result; a promisified wrapper compresses that into one async/await call, with the same shape carried through stored procedure calls, batch execution and connection setup from environment configuration. The repository holds four packages across three languages: hdb and hdbext for Node.jsNode.jsA cross-platform JavaScript runtime that servers, command line tools and scripts written in JavaScript are run with. For the things here, the prerequisite a repository names when its build is a set of npm scripts., published to npm as sap-hdb-promisfied and sap-hdbext-promisfied, hdbhelper for Go, tagged in the repository and fetched through the Go module proxy, and hdbhelper-py for Python, published to PyPI. It wraps connection handling and querying. Which client library to wrap is the caller's choice, and so are the credentials, which the class reads from a default-env.json in the working directory rather than from code.
Facts
Where it sits
Who is behind it
In the atlas: maintains 222@SAP-samplesmaintainerAjinkya PatilContributes to this
In the atlas: contributes to 112@ajinkyapatil8190Brian BernardContributes to this
In the atlas: contributes to 64@btbernardThomas JungContributes to this
Developer Advocate
In the atlas: contributes to 15, wrote 6@jung-thomasLars HvamContributes to this
In the atlas: maintains 13, contributes to 92, wrote 1@larshpmmicciolo-sapContributes to this
In the atlas: contributes to 1@mmicciolo-sap5 contributors
What it declares
Every artifact
- Type
- Package
- Origin
- By SAP
- Runtime
- Node.js
As a package
- Where it runs
- In your own program
- Distributed through
- npmPyPI
Connections
Connecting a data model and its queries to a database
Download
Install
npm add SAP-samples/hana-hdbext-promisfied-exampleDerived from the package name. No recipe recorded; the README has the configuration.
README
quoted from SAP-samples/hana-hdbext-promisfied-example under Apache-2.0, readSAP HANA Client Helpers — Node.js, Go & Python
Description
This repository contains high-level wrappers for SAP HANA client libraries, simplifying connection management, query execution, and stored procedure invocation in Node.js, Go, and Python:
| Package | Language | Wraps | Runtime |
|---|---|---|---|
hdb/ | Node.js | hdb | ^20 || ^22 || ^24 |
hdbext/ | Node.js | @sap/hdbext | >=18.18.0 |
hdbhelper/ | Go | SAP/go-hdb | Go 1.22+ |
hdbhelper-py/ | Python | hdbcli | Python 3.12+ |
The Node.js packages expose an ES6 class API (dbClass) with dual ESM/CJS entry points (index.js / index.cjs). The Go package provides an equivalent API surface using idiomatic Go patterns. The Python package wraps hdbcli with the same connection-from-environment and stored procedure patterns.
Motivation
With the standard @sap/hdbext you use nested callbacks like this:
let client = req.db;
client.prepare(
`SELECT SESSION_USER, CURRENT_SCHEMA FROM "DUMMY"`,
(err, statement) => {
if (err) return res.status(500).send(`ERROR: ${err.toString()}`);
statement.exec([], (err, results) => {
if (err) return res.status(500).send(`ERROR: ${err.toString()}`);
return res.status(200).json({ Objects: results });
});
});
With sap-hdbext-promisfied the same code becomes:
try {
const dbClass = require("sap-hdbext-promisfied")
let db = new dbClass(req.db);
const statement = await db.preparePromisified(`SELECT SESSION_USER, CURRENT_SCHEMA FROM "DUMMY"`)
const results = await db.statementExecPromisified(statement, [])
return res.status(200).json({ Objects: results })
} catch (e) {
return res.status(500).send(`ERROR: ${e.toString()}`)
}
Installation
# hdbext variant
npm install sap-hdbext-promisfied
# hdb variant (no @sap/hana-client dependency)
npm install sap-hdb-promisfied
Both packages are published to the default npm registry (https://registry.npmjs.org).
Note: If you previously configured a custom
@sap:registry, remove it:npm config delete @sap:registry
Usage
Creating a connection
Pass an existing HANA client instance directly:
import dbClass from 'sap-hdbext-promisfied'
const db = new dbClass(req.db) // req.db from Express middleware
Or let the class create and manage the connection from environment configuration:
import dbClass from 'sap-hdbext-promisfied'
const db = new dbClass(await dbClass.createConnectionFromEnv(dbClass.resolveEnv(null)))
For sap-hdb-promisfied, call db.destroyClient() when done to close the connection:
import dbClass from 'sap-hdb-promisfied'
const db = new dbClass(await dbClass.createConnectionFromEnv(dbClass.resolveEnv(null)))
try {
const results = await db.execSQL(`SELECT CURRENT_USER FROM DUMMY`)
console.table(results)
} finally {
db.destroyClient()
}
Querying
// Convenience: prepare + exec in one call
const results = await db.execSQL(`SELECT SESSION_USER, CURRENT_SCHEMA FROM "DUMMY"`)
// Or step by step for parameterised queries
const statement = await db.preparePromisified(`SELECT * FROM "MY_TABLE" WHERE ID = ?`)
const results = await db.statementExecPromisified(statement, [42])
// Batch execution
await db.statementExecBatchPromisified(statement, [[1], [2], [3]])
Stored procedures
hdbext package — uses hdbext.loadProcedure:
import * as hdbext from '@sap/hdbext'
const sp = await db.loadProcedurePromisified(hdbext, 'SYS', 'IS_VALID_PASSWORD')
const { outputScalar, results } = await db.callProcedurePromisified(sp, { PASSWORD: 'MyPass1234' })
hdb package — resolves procedure metadata via SQL, no hdbext dependency:
const sp = await db.loadProcedurePromisified('SYS', 'IS_VALID_PASSWORD')
const { outputScalar, results } = await db.callProcedurePromisified(sp, [])
Procedure output shape:
- Single result set →
{ outputScalar, results } - Multiple result sets →
{ outputScalar, results0, results1, ... }
API Reference
Instance methods
| Method | Description |
|---|---|
preparePromisified(query) | Prepare a SQL statement; returns a statement object |
statementExecPromisified(statement, params) | Execute a prepared statement |
statementExecBatchPromisified(statement, params) | Execute a prepared statement in batch |
loadProcedurePromisified(...) | Load a stored procedure (signature differs by package — see above) |
callProcedurePromisified(storedProc, inputParams) | Call a loaded stored procedure |
execSQL(sql) | Prepare + execute a statement and return the result set |
destroyClient() | (hdb only) Close the underlying connection |
validateClient() | (hdb only) Returns true if the connection is open and healthy |
Static helpers
| Method | Description |
|---|---|
createConnectionFromEnv(envFile) | Load connection config from env files and open a connection |
createConnection(options) | Open a connection with explicit options |
resolveEnv(options) | Resolve path to default-env.json; pass { admin: true } for default-env-admin.json |
schemaCalc(options, db) | Resolve schema: **CURRENT_SCHEMA** → live value, * → % |
objectName(name) | Expand * / null / undefined → %; otherwise append % |
fetchSPMetadata(db, procInfo) | (hdb only) Fetch stored procedure parameter metadata from SYS.PROCEDURE_PARAMETERS |
Environment Configuration
Connection credentials are never stored in code. Create a default-env.json file in the working directory (git-ignored):
{
"VCAP_SERVICES": {
"hana": [{
"name": "my-hana-service",
"tags": ["hana"],
"credentials": {
"host": "...",
"port": 443,
"user": "...",
"password": "...",
"encrypt": true
}
}]
}
}
- Use
default-env-admin.jsonfor admin-level connections (pass{ admin: true }toresolveEnv). - Set
TARGET_CONTAINERenvironment variable to select a specific service binding by name rather than by tag. - The
hdbpackage automatically enables TLS (useTLS: true) whenencrypt: trueis present in the credentials.
CI / CD
Continuous Integration
Every push to main and every pull request runs four parallel jobs via GitHub Actions (.github/workflows/ci.yml):
| Job | What it checks | Matrix |
|---|---|---|
| test-hdb | npm install → npm test → npm run types | Node.js 20, 22 |
| test-hdbext | npm install → npm test → npm run types | Node.js 20, 22 |
| test-hdbhelper | go build → go vet → go test -v | Go 1.25 |
| test-hdbhelper-py | pip install → pytest -v | Python 3.12, 3.13 |
All test suites include integration tests that require a live SAP HANA instance. When HANA is unreachable (as in CI), these tests auto-skip — the suite still passes. Unit tests always run.
Releasing the Go module
Go modules are distributed directly from the Git repository — there is no registry to publish to. The Go module proxy (proxy.golang.org) caches modules automatically when users run go get.
To release a new version of hdbhelper:
- Go to Actions → Release Go Module → Run workflow
- Enter a semver version (e.g.
0.1.0) - The workflow validates, builds, tests, then creates a
hdbhelper/v0.1.0tag and pushes it
The subdirectory prefix on the tag (hdbhelper/v...) is required by Go for modules that live in a subdirectory of a repository. After the tag is pushed, anyone can install the module:
go get github.com/SAP-samples/hana-hdbext-promisfied-example/hdbhelper@v0.1.0
Releasing the Python package
The Python package (sap-hdbhelper-py) is published to PyPI using GitHub Actions with trusted publishers (OIDC — no stored API tokens).
To release a new version of hdbhelper-py:
- Go to Actions → Release Python Package → Run workflow
- Enter a semver version (e.g.
0.1.0) - The workflow validates, tests, bumps
pyproject.toml, builds sdist + wheel, commits, creates ahdbhelper-py/v0.1.0tag, and publishes to PyPI
After publishing, anyone can install the package:
pip install sap-hdbhelper-py
First-time setup: Before the first release, configure a pending trusted publisher on PyPI for project
sap-hdbhelper-py, ownerSAP-samples, repohana-hdbext-promisfied-example, workflowrelease-python.yml, environmentpypi. Also create a GitHub Environment namedpypiin repo Settings → Environments.
Releasing the Node.js packages
The Node.js packages (sap-hdb-promisfied, sap-hdbext-promisfied) are published to npm using GitHub Actions with provenance attestation.
To release:
- Go to Actions → Release Node.js Package → Run workflow
- Select a package (
hdb,hdbext, orboth) - Enter a semver version (e.g.
2.202604.1) - The workflow tests, generates type declarations, bumps
package.json+npm-shrinkwrap.json, publishes with provenance, commits, createshdb/vX.Y.Zand/orhdbext/vX.Y.Ztags, and pushes
Setup: Add an npm automation access token as the
NPM_TOKENsecret in repo Settings → Secrets and variables → Actions.
Known Issues
None
How to obtain support
This project is provided "as-is": there is no guarantee that raised issues will be answered or addressed in future releases.
License
Copyright (c) 2026 SAP SE or an SAP affiliate company. All rights reserved. This project is licensed under the Apache Software License, version 2.0 except as noted otherwise in the LICENSE file.
Others providing
Compare all 26 on the Database connectors page →- SAP ASE ServiceSAP ASE ServiceSAP ASE database systems and tenant databases on BTP with SAP running the platform operations, used from Java applications on BTP or on premise over SQL, JPA and JDBC.sap official, btpManaged SAP ASE databases on BTP for Java applicationsfrom BTP/BAIP
- SAP HANA CloudSAP HANA CloudThe managed database under most of this: CAP's default target, the store Datasphere and Analytics Cloud sit on, and a service with plans and components.sap official, btpManaged SAP HANA database service on BTPfrom BTP/BAIP
- SAP HANA Service (SAP Regions) for SAP BTPSAP HANA Service (SAP Regions) for SAP BTPManaged SAP HANA 2.0 database systems in fixed sizes from 64 GB to 1 TB, in SAP's own regions, with tenant databases bound to applications on SAP BTP.sap official, btpManaged SAP HANA 2.0 databases in fixed sizes on SAP BTPfrom BTP/BAIP
- PostgreSQL on SAP BTP, hyperscaler optionPostgreSQL on SAP BTP, hyperscaler optionA managed PostgreSQL from the underlying hyperscaler — AWS, Azure, Google Cloud or Alicloud — consumed through a BTP service binding.sap official, btpManaged PostgreSQL from the hyperscaler via a BTP service bindingfrom BTP/BAIP
- com.sap.cds:cds-feature-hanacom.sap.cds:cds-feature-hanaThe CAP Java feature that wires a Maven application to SAP HANA Cloud, the production default among CAP's supported databases.sap official, capSAP HANA Cloud datasource for CAP Java applicationsfrom CAP
- com.sap.cds:cds-feature-jdbccom.sap.cds:cds-feature-jdbcConnects the CAP Java runtime to JDBC databases through the CDS4j JDBC runtime: H2 and SQLite, which capire names for local development and CI tests rather than enterprise use.sap official, capJDBC runtime for H2 and SQLite in CAP Javafrom CAP
- com.sap.cds:cds-feature-postgresqlcom.sap.cds:cds-feature-postgresqlThe CAP Java feature that wires a Maven application to PostgreSQL as its datasource beside SAP HANA, with limitations capire lists: schema evolution first, and no multitenancy or extensibility yet.sap official, capPostgreSQL datasource for CAP Java applicationsfrom CAP
- com.sap.cds:cds-services-bomcom.sap.cds:cds-services-bomThe Maven bill of materials for CAP Java, pinning every com.sap.cds module in a release, from the API and core runtime to the Spring Boot starters and the CQN engine, to the same version.sap official, capMaven bill of materials pinning CAP Java module versionsfrom CAP
- @cap-js/db-service@cap-js/db-serviceThe base every CAP database service is built on: the shared query translation and pooling that SQLite, PostgreSQL and HANA specialise rather than reimplement.sap official, capBase service shared by CAP's SQLite, PostgreSQL and HANA servicesfrom CAP
- @cap-js/hana@cap-js/hanaThe HANA database service — the production default, on the same streamlined architecture as the SQLite and PostgreSQL services.sap official, capSAP HANA database service for CAPfrom CAP
- @cap-js/postgres@cap-js/postgresThe PostgreSQL database service — the production option for running CAP off HANA, sharing the base service with the other three.sap official, capPostgreSQL database service for CAPfrom CAP
- @cap-js/sqlite@cap-js/sqliteThe SQLite service, in memory during the inner loop — which is why a CAP project runs before anyone has provisioned a database.sap official, capSQLite database service for CAP, in memory during developmentfrom CAP
- cap-postgres-btp-connectivitycap-postgres-btp-connectivityConnects a CAP Node.js application to a PostgreSQL database that is not publicly reachable, tunnelling through BTP Connectivity and the Cloud Connector.independent, capTunnels CAP Node.js to a private PostgreSQL via Cloud Connectorfrom CAP
- cds-mongodbcds-mongodbMongoDB as a native CAP database service, through Mongoose — CQN reads and writes, managed associations as ObjectId references, $expand resolved by populate, and cds deploy --to mongoose.independent, capMongoDB as a CAP database service through Mongoosefrom CAP
- @cds-pgroll/postgres@cds-pgroll/postgresThe destructive half of PostgreSQL schema evolution — DROP and RENAME, which CAP's own schema_evolution: alter will not perform — driven from the command line beside @cap-js/postgres.independent, capCLI for DROP and RENAME schema changes beside @cap-js/postgresfrom CAP
- hdbhdbSAP's HANA driver for Node.js, written entirely in JavaScript so installing it pulls in no native client, running SQL against SAP HANA and SAP HANA Cloud with streams and prepared statements.sap official, btpPure JavaScript SAP HANA driver for Node.jsfrom BTP/BAIP
- @neoimpulse/cap-js-restore-model-defined-types@neoimpulse/cap-js-restore-model-defined-typesA CAP plugin that casts values back to the types the CDS model declares after a READ, for the entities you name, where the database driver returned them as strings.independent, capCAP plugin casting read values back to CDS model typesfrom CAP
- @quadrio/cds-db2@quadrio/cds-db2A DB2 adapter for CDS, so a CAP model can be deployed to and served from DB2, last released July 2023 and still on npm while the repository it was published from has been deleted.independent, capDB2 adapter for CDSfrom CAP
- @sap/cds-hana@sap/cds-hanaThe SAP Cloud Application Programming Model's database adapter for SAP HANA, the package a CAP project adds to run its model on a SAP HANA database.sap official, capDatabase adapter for SAP HANA in CAPfrom CAP
- @sap/cds@sap/cdsThe CAP Node.js runtime, which compiles the CDS model, serves the services declared in it, answers generic requests before any handler runs, and loads every cds-plugin.sap official, capCAP Node.js runtimefrom CAP
- @sap/hana-client@sap/hana-clientSAP's own Node.js driver for SAP HANA: connect, run SQL and prepared statements, synchronously, through callbacks or as promises, over native client libraries npm installs per platform.sap official, btpSAP's Node.js driver for SAP HANAfrom BTP/BAIP
- SAP HANASAP HANASAP’s relational database platform, which stores application data and executes SQL and SQLScript in the database, available on-premise and as the managed service SAP HANA Cloud.sap official, btpSAP's relational database platform, on-premise and in HANA Cloudfrom BTP/BAIP
- cds-pgcds-pgA PostgreSQL adapter for SAP CDS, built by the SAP Mentors community, which gave CAP a Postgres persistence option years before @cap-js/postgres shipped.independent, capPostgreSQL adapter for SAP CDS from the SAP Mentors communityfrom CAP
- cap-snowflakecap-snowflakeA CAP database adapter for Snowflake with OData V4 support, which the maintainer marks as early development, so its contract is expected to move.independent, capCAP database adapter for Snowflake with OData V4 supportfrom CAP
- cds-mysqlcds-mysqlA MySQL and MariaDB database adapter for CAP that connects to a database instance and translates incoming CQL/CQN requests to it; the repository the package declares has been deleted.independent, capMySQL and MariaDB database adapter for CAPfrom CAP
Details
Sources
Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.
Compatibility and provenance
History in the atlas
- First seen.
For your agent
- Ref
artifact:sap-samples-hana-hdbext-promisfied-example- JSON
- /artifacts/sap-samples-hana-hdbext-promisfied-example.json
- MCP
- Connecting an agent