Skip to main content

Relational Database (PostgreSQL)

version tip

Since @cloudbase/manager-node@5.4.0, this module has been added. Accessed via app.database, it provides the ability to execute SQL statements and manage data on PostgreSQL-based CloudBase environments.


Initialize​

import CloudBase from '@cloudbase/manager-node'

const app = CloudBase.init({
secretId: 'Your SecretId',
secretKey: 'Your SecretKey',
envId: 'Your envId'
})

const { database } = app

executePGSql​

1. API Description​

Function: Execute any SQL statement (DDL / DML / DQL, etc.) on a PostgreSQL environment, returning the result set and affected row count.

Declaration: app.database.executePGSql(options): Promise<IExecutePGSqlResult>

2. Input Parameters​

IExecutePGSqlOptions

FieldRequiredTypeDescription
SqlYesStringThe SQL statement to execute
RoleNoStringSpecify a role to execute the SQL. Accepts any valid role, including user-defined roles. CloudBase provides a built-in read-only role cloudbase_read_only_user; using it prevents unintended write operations from succeeding
EnvIdNoStringCloudBase environment ID. If not provided, the EnvId used during manager instance initialization will be used

3. Response​

IExecutePGSqlResult

FieldTypeDescription
RequestIdStringUnique request identifier
AffectedRowsNumberNumber of affected rows (effective for DML statements)
ColumnsString[] / nullList of column names (returned for SELECT statements); null when there is no result set
RowsString[] / nullList of data rows, each item is a JSON string that deserializes to (string | null)[], aligned with Columns order; null when there is no result set
ExecutionTimeMsNumberSQL execution time (milliseconds)

4. Code Example​

// Create a table
await database.executePGSql({
Sql: 'CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT NOT NULL, email TEXT UNIQUE)'
})

// Insert data
const insertRes = await database.executePGSql({
Sql: "INSERT INTO users (name, email) VALUES ('Alice', 'alice@example.com')"
})
console.log('Affected rows:', insertRes.AffectedRows) // 1

// Query and parse results
const res = await database.executePGSql({
Sql: 'SELECT id, name, email FROM users WHERE id = 1'
})
console.log(res.Columns) // ['id', 'name', 'email']
const rows = (res.Rows || []).map(s => JSON.parse(s))
// rows: [['1', 'Alice', 'alice@example.com']]

// Use the built-in read-only role to run a query, preventing unintended write operations from succeeding
const readonlyRes = await database.executePGSql({
Role: 'cloudbase_read_only_user',
Sql: 'SELECT id, name, email FROM users'
})
console.log(readonlyRes.Rows)

// Execute on a different environment ID
await database.executePGSql({
EnvId: 'other-env-id',
Sql: 'SELECT NOW()'
})

Database Migrations​

version tip

Since @cloudbase/manager-node@5.6.5, the following database migration methods have been added, allowing you to manage schema and data changes on PostgreSQL-based CloudBase environments using versioned SQL scripts.

Concepts​

  • Migration: A versioned SQL change consisting of Version, Name, Query.
    • Version: A 14-digit numeric timestamp such as 20260526000000. Using an actual timestamp (YYYYMMDDHHMMSS) is recommended to guarantee global ordering and uniqueness.
    • Name: Lowercase letters and underscores only, e.g. create_users_table.
    • Query: The SQL to execute.
  • cloudbase_migrations.schema_migrations: The migration history table maintained by CloudBase on the target PG environment, recording all successfully applied migrations.
  • Typical workflow:
    1. Preview the plan and check checksum conflicts with previewPGUserMigrations.
    2. If there are no conflicts, call pushPGUserMigrations and get a TaskId.
    3. Poll the task status via describeTaskResult until it reaches Succeed / Failed.
    4. Query applied records via listPGUserMigrations / listAllPGUserMigrations / describePGUserMigration when needed.
    5. When the history is out of sync with the database, use repairPGUserMigrationHistory to fix the history records only (no SQL is executed).

previewPGUserMigrations​

1. API Description​

Function: Preview the remote execution plan for a batch of user migrations (no SQL is actually executed). Returns Pending, Applied, Conflicts (checksum conflicts) and Executable.

Declaration: app.database.previewPGUserMigrations(options): Promise<IPreviewPGUserMigrationsResult>

2. Input Parameters​

IPreviewPGUserMigrationsOptions

FieldRequiredTypeDescription
EnvIdNoStringCloudBase environment ID. Falls back to the EnvId used during manager initialization
MigrationsYesIPGUserMigrationInput[]Migration list, at least 1 item; each item must pass the validations below
IncludeAllNoBooleanWhether to allow out-of-order local migrations (inserting a new version before an already applied one). Default false

IPGUserMigrationInput

FieldRequiredTypeDescription
VersionYesStringMigration version, a 14-digit numeric timestamp (e.g. 20260526000000)
NameYesStringMigration name, lowercase letters and underscores only
QueryYesStringThe SQL to execute; must not be empty

3. Response​

IPreviewPGUserMigrationsResult

FieldTypeDescription
PendingIPGUserMigrationPlanItem[] | nullMigrations that will be executed
AppliedIPGUserMigrationPlanItem[] | nullMigrations that have already been applied
ConflictsIPGUserMigrationConflict[] | nullConflicts: migrations with the same version but a different checksum. Non-empty means local SQL differs from applied records
ExecutableBooleanWhether the plan can be executed directly (currently means no checksum conflicts)
RequestIdStringUnique request identifier

Main fields of IPGUserMigrationPlanItem: Version, Name, Status (e.g. applied / pending), Reason (e.g. checksum_matched), Checksum, Source.

Main fields of IPGUserMigrationConflict: Version, Name, RemoteName, LocalChecksum, RemoteChecksum, Reason (e.g. checksum_mismatch), Message.

4. Code Example​

const preview = await database.previewPGUserMigrations({
Migrations: [
{
Version: '20260526000000',
Name: 'create_users_table',
Query:
'CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name TEXT NOT NULL);'
}
]
})

if (!preview.Executable || (preview.Conflicts || []).length > 0) {
console.error('Checksum conflicts must be resolved first:', preview.Conflicts)
return
}

console.log('Pending:', preview.Pending)
console.log('Applied:', preview.Applied)

pushPGUserMigrations​

1. API Description​

Function: Apply a batch of user migrations. This is an asynchronous task: it returns a TaskId on success. Use describeTaskResult to query the final result.

Declaration: app.database.pushPGUserMigrations(options): Promise<IPushPGUserMigrationsResult>

2. Input Parameters​

IPushPGUserMigrationsOptions

FieldRequiredTypeDescription
EnvIdNoStringCloudBase environment ID. Falls back to the EnvId used during manager initialization
MigrationsYesIPGUserMigrationInput[]Migration list, at least 1 item; same field validations as previewPGUserMigrations
LockTimeoutMsNoNumberMaximum wait time (ms) to acquire the database lock; must be >= 0. Default 5000
StatementTimeoutMsNoNumberMaximum execution time (ms) for a single SQL statement; must be >= 0. Default 300000
IncludeAllNoBooleanWhether to allow out-of-order local migrations. Default false

3. Response​

IPushPGUserMigrationsResult

FieldTypeDescription
RequestIdStringUnique request identifier
TaskIdStringAsync task ID, used to query task progress and status

4. Code Example​

// 1. Submit the async task
const { TaskId } = await database.pushPGUserMigrations({
Migrations: [
{
Version: '20260526000000',
Name: 'create_users_table',
Query:
'CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name TEXT NOT NULL);'
}
],
LockTimeoutMs: 5000,
StatementTimeoutMs: 60000
})

// 2. Poll the task status
async function waitTask(taskId) {
while (true) {
const task = await database.describeTaskResult({ TaskId: taskId })
if (task.Status === 'Succeed' || task.Status === 'Failed') {
return task
}
await new Promise(r => setTimeout(r, 1000))
}
}

const result = await waitTask(TaskId)
console.log('Task finished:', result.Status, result.Phase, result.Reason)

repairPGUserMigrationHistory​

1. API Description​

Function: Only maintain records in the cloudbase_migrations.schema_migrations history table. No SQL is executed. Typical use cases:

  • SQL was applied out-of-band and the history table is missing the corresponding record (use applied to insert it).
  • A migration recorded in history needs to be withdrawn (use reverted to delete the record).

Declaration: app.database.repairPGUserMigrationHistory(options): Promise<IResponseInfo>

2. Input Parameters​

IRepairPGUserMigrationHistoryOptions

FieldRequiredTypeDescription
EnvIdNoStringCloudBase environment ID. Falls back to the EnvId used during manager initialization
MigrationVersionYesStringMigration version, a 14-digit numeric timestamp
NameYesStringMigration name, lowercase letters and underscores only
StatusYes'applied' | 'reverted'applied inserts into history; reverted deletes from history
ReasonYesStringReason for the repair; cannot be empty
QueryNoStringRequired when Status=applied, should be the corresponding SQL; can be omitted when Status=reverted

3. Response​

IResponseInfo: contains common fields such as RequestId.

4. Code Example​

// Insert a migration that was applied out-of-band
await database.repairPGUserMigrationHistory({
MigrationVersion: '20260526000000',
Name: 'create_users_table',
Status: 'applied',
Reason: 'Applied manually out-of-band, backfill history',
Query: 'CREATE TABLE IF NOT EXISTS users (id SERIAL PRIMARY KEY, name TEXT NOT NULL);'
})

// Remove an incorrectly recorded migration from history
await database.repairPGUserMigrationHistory({
MigrationVersion: '20260526000000',
Name: 'create_users_table',
Status: 'reverted',
Reason: 'Recorded by mistake; remove from history'
})

listPGUserMigrations​

1. API Description​

Function: Paginated query of applied migrations on the target environment.

Declaration: app.database.listPGUserMigrations(options?): Promise<IListPGUserMigrationsResult>

2. Input Parameters​

IListPGUserMigrationsOptions (all optional)

FieldRequiredTypeDescription
EnvIdNoStringCloudBase environment ID. Falls back to the initialization EnvId
LimitNoNumberPage size, range [1, 500], default 100
OffsetNoNumberPagination offset, >= 0, default 0

3. Response​

IListPGUserMigrationsResult

FieldTypeDescription
TotalNumberTotal count
LatestVersionStringLatest applied version (14-digit numeric timestamp)
MigrationsIPGUserMigrationSummary[]Applied migrations, each item contains Version and Name
RequestIdStringUnique request identifier

4. Code Example​

const page = await database.listPGUserMigrations({ Limit: 100, Offset: 0 })
console.log('Total:', page.Total, 'Latest version:', page.LatestVersion)
page.Migrations.forEach(m => {
console.log(m.Version, m.Name)
})

listAllPGUserMigrations​

1. API Description​

Function: Auto-paginate and return all applied migrations on the target environment. Internally repeats listPGUserMigrations with PageSize until finished.

Declaration: app.database.listAllPGUserMigrations(options?): Promise<IListPGUserMigrationsResult>

2. Input Parameters​

IListAllPGUserMigrationsOptions (all optional)

FieldRequiredTypeDescription
EnvIdNoStringCloudBase environment ID. Falls back to the initialization EnvId
PageSizeNoNumberInternal page size, range [1, 500], default 500

3. Response​

Same as listPGUserMigrations: IListPGUserMigrationsResult. The returned Migrations is the full list.

4. Code Example​

const all = await database.listAllPGUserMigrations()
console.log('Total applied:', all.Migrations.length)
console.log('Latest version:', all.LatestVersion)

describePGUserMigration​

1. API Description​

Function: Get the details (including the SQL body) of a specific migration on the target environment.

Declaration: app.database.describePGUserMigration(options): Promise<IDescribePGUserMigrationResult>

2. Input Parameters​

IDescribePGUserMigrationOptions

FieldRequiredTypeDescription
EnvIdNoStringCloudBase environment ID. Falls back to the initialization EnvId
MigrationVersionYesStringMigration version, a 14-digit numeric timestamp

3. Response​

IDescribePGUserMigrationResult

FieldTypeDescription
VersionStringMigration version
NameStringMigration name
QueryStringThe SQL body of the migration
RequestIdStringUnique request identifier

4. Code Example​

const detail = await database.describePGUserMigration({
MigrationVersion: '20260526000000'
})
console.log(detail.Version, detail.Name)
console.log(detail.Query)

describeTaskResult​

1. API Description​

Function: Query the execution status of an asynchronous task (such as the task returned by pushPGUserMigrations). Can be used to poll until the task reaches a terminal state.

Declaration: app.database.describeTaskResult(options): Promise<IDescribeTaskResultResult>

2. Input Parameters​

IDescribeTaskResultOptions

FieldRequiredTypeDescription
EnvIdNoStringCloudBase environment ID. Falls back to the initialization EnvId
TaskIdYesStringTask ID; cannot be empty

3. Response​

IDescribeTaskResultResult

FieldTypeDescription
TaskIdStringTask ID
TaskTypeStringTask type (e.g. PGUserMigration)
StatusStringTask status: Accepted / Running / Succeed / Failed
PhaseStringCurrent phase
ReasonStringFailure reason (may be empty on success)
CreatedAtStringCreated time (ISO 8601)
UpdatedAtStringLast updated time (ISO 8601)
RequestIdStringUnique request identifier

4. Code Example​

const task = await database.describeTaskResult({ TaskId: 'task-xxxxxx' })
if (task.Status === 'Succeed') {
console.log('Task succeeded, updated at', task.UpdatedAt)
} else if (task.Status === 'Failed') {
console.error('Task failed:', task.Phase, task.Reason)
} else {
console.log('Task in progress:', task.Status, task.Phase)
}