Skip to main content 首页 创作者 beko2210 firstbrain azure-postgres-ts
azure-postgres-ts Connect to Azure Database for PostgreSQL Flexible Server from Node.js/TypeScript using the pg (node-postgres) package.
跳到安装 Skills Marketplace 发现并探索由社区构建的 Agent Skills
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/BEKO2210/Firstbrain --skill azure-postgres-ts命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
下载 Zip 下载中... name azure-postgres-ts description Connect to Azure Database for PostgreSQL Flexible Server from Node.js/TypeScript using the pg (node-postgres) package. type skill created 2026-02-27T00:00:00.000Z domain cloud-infrastructure category azure risk unknown source community tags ["skill","cloud-infrastructure","azure","postgres"]
Azure PostgreSQL for TypeScript (node-postgres)
Connect to Azure Database for PostgreSQL Flexible Server using the pg (node-postgres) package with support for password and Microsoft Entra ID (passwordless) authentication.
Installation
npm install pg @azure/identity
npm install -D @types/pg
Environment Variables
AZURE_POSTGRESQL_HOST=<server>.postgres.database.azure.com
AZURE_POSTGRESQL_DATABASE=<database>
AZURE_POSTGRESQL_PORT=5432
AZURE_POSTGRESQL_USER=<username>
AZURE_POSTGRESQL_PASSWORD=<password>
AZURE_POSTGRESQL_USER=<entra-user>@<server>
AZURE_POSTGRESQL_CLIENTID=<managed-identity-client-id>
Authentication
Option 1: Password Authentication
import { Client , Pool } from "pg" ;
const client = new Client ({
host : process.env .AZURE_POSTGRESQL_HOST ,
database : process.env .AZURE_POSTGRESQL_DATABASE ,
user : process.env .AZURE_POSTGRESQL_USER ,
password : process.env .AZURE_POSTGRESQL_PASSWORD ,
port : Number (process.env .AZURE_POSTGRESQL_PORT ) || 5432 ,
ssl : { rejectUnauthorized : true }
});
await client. ();
connect
Option 2: Microsoft Entra ID (Passwordless) - Recommended import { Client , Pool } from "pg" ;
import { DefaultAzureCredential } from "@azure/identity" ;
const credential = new DefaultAzureCredential ();
const tokenResponse = await credential.getToken (
"https://ossrdbms-aad.database.windows.net/.default"
);
const client = new Client ({
host : process.env .AZURE_POSTGRESQL_HOST ,
database : process.env .AZURE_POSTGRESQL_DATABASE ,
user : process.env .AZURE_POSTGRESQL_USER ,
password : tokenResponse.token ,
port : Number (process.env .AZURE_POSTGRESQL_PORT ) || 5432 ,
ssl : { rejectUnauthorized : true }
});
await client.connect ();
Core Workflows
1. Single Client Connection import { Client } from "pg" ;
const client = new Client ({
host : process.env .AZURE_POSTGRESQL_HOST ,
database : process.env .AZURE_POSTGRESQL_DATABASE ,
user : process.env .AZURE_POSTGRESQL_USER ,
password : process.env .AZURE_POSTGRESQL_PASSWORD ,
port : 5432 ,
ssl : { rejectUnauthorized : true }
});
try {
await client.connect ();
const result = await client.query ("SELECT NOW() as current_time" );
console .log (result.rows [0 ].current_time );
} finally {
await client.end ();
}
2. Connection Pool (Recommended for Production) import { Pool } from "pg" ;
const pool = new Pool ({
host : process.env .AZURE_POSTGRESQL_HOST ,
database : process.env .AZURE_POSTGRESQL_DATABASE ,
user : process.env .AZURE_POSTGRESQL_USER ,
password : process.env .AZURE_POSTGRESQL_PASSWORD ,
port : 5432 ,
ssl : { rejectUnauthorized : true },
max : 20 ,
idleTimeoutMillis : 30000 ,
connectionTimeoutMillis : 10000
});
const result = await pool.query ("SELECT * FROM users WHERE id = $1" , [userId]);
const client = await pool.connect ();
try {
const res1 = await client.query ("SELECT * FROM users" );
const res2 = await client.query ("SELECT * FROM orders" );
} finally {
client.release ();
}
await pool.end ();
3. Parameterized Queries (Prevent SQL Injection)
const userId = 123 ;
const email = "user@example.com" ;
const result = await pool.query (
"SELECT * FROM users WHERE id = $1" ,
[userId]
);
const result = await pool.query (
"INSERT INTO users (email, name, created_at) VALUES ($1, $2, NOW()) RETURNING *" ,
[email, "John Doe" ]
);
const ids = [1 , 2 , 3 , 4 , 5 ];
const result = await pool.query (
"SELECT * FROM users WHERE id = ANY($1::int[])" ,
[ids]
);
4. Transactions const client = await pool.connect ();
try {
await client.query ("BEGIN" );
const userResult = await client.query (
"INSERT INTO users (email) VALUES ($1) RETURNING id" ,
["user@example.com" ]
);
const userId = userResult.rows [0 ].id ;
await client.query (
"INSERT INTO orders (user_id, total) VALUES ($1, $2)" ,
[userId, 99.99 ]
);
await client.query ("COMMIT" );
} catch (error) {
await client.query ("ROLLBACK" );
throw error;
} finally {
client.release ();
}
5. Transaction Helper Function async function withTransaction<T>(
pool : Pool ,
fn : (client : PoolClient ) => Promise <T>
): Promise <T> {
const client = await pool.connect ();
try {
await client.query ("BEGIN" );
const result = await fn (client);
await client.query ("COMMIT" );
return result;
} catch (error) {
await client.query ("ROLLBACK" );
throw error;
} finally {
client.release ();
}
}
const order = await withTransaction (pool, async (client) => {
const user = await client.query (
"INSERT INTO users (email) VALUES ($1) RETURNING *" ,
["user@example.com" ]
);
const order = await client.query (
"INSERT INTO orders (user_id, total) VALUES ($1, $2) RETURNING *" ,
[user.rows [0 ].id , 99.99 ]
);
return order.rows [0 ];
});
6. Typed Queries with TypeScript import { Pool , QueryResult } from "pg" ;
interface User {
id : number ;
email : string ;
name : string ;
created_at : Date ;
}
const result : QueryResult <User > = await pool.query <User >(
"SELECT * FROM users WHERE id = $1" ,
[userId]
);
const user : User | undefined = result.rows [0 ];
async function createUser (
pool : Pool ,
email : string ,
name : string
): Promise <User > {
const result = await pool.query <User >(
"INSERT INTO users (email, name) VALUES ($1, $2) RETURNING *" ,
[email, name]
);
return result.rows [0 ];
}
Pool with Entra ID Token Refresh For long-running applications, tokens expire and need refresh:
import { Pool , PoolConfig } from "pg" ;
import { DefaultAzureCredential , AccessToken } from "@azure/identity" ;
class AzurePostgresPool {
private pool : Pool | null = null ;
private credential : DefaultAzureCredential ;
private tokenExpiry : Date | null = null ;
private config : Omit <PoolConfig , "password" >;
constructor (config : Omit <PoolConfig , "password" > ) {
this .credential = new DefaultAzureCredential ();
this .config = config;
}
private async getToken (): Promise <string > {
const tokenResponse = await this .credential .getToken (
"https://ossrdbms-aad.database.windows.net/.default"
);
this .tokenExpiry = new Date (tokenResponse.expiresOnTimestamp );
return tokenResponse.token ;
}
private isTokenExpired (): boolean {
if (!this .tokenExpiry ) return true ;
return new Date () >= new Date (this .tokenExpiry .getTime () - 5 * 60 * 1000 );
}
async getPool (): Promise <Pool > {
if (this .pool && !this .isTokenExpired ()) {
return this .pool ;
}
if (this .pool ) {
await this .pool .end ();
}
const token = await this .getToken ();
this .pool = new Pool ({
...this .config ,
password : token
});
return this .pool ;
}
async query<T>(text : string , params ?: any []): Promise <QueryResult <T>> {
const pool = await this .getPool ();
return pool.query <T>(text, params);
}
async end (): Promise <void > {
if (this .pool ) {
await this .pool .end ();
this .pool = null ;
}
}
}
const azurePool = new AzurePostgresPool ({
host : process.env .AZURE_POSTGRESQL_HOST !,
database : process.env .AZURE_POSTGRESQL_DATABASE !,
user : process.env .AZURE_POSTGRESQL_USER !,
port : 5432 ,
ssl : { rejectUnauthorized : true },
max : 20
});
const result = await azurePool.query ("SELECT NOW()" );
Error Handling import { DatabaseError } from "pg" ;
try {
await pool.query ("INSERT INTO users (email) VALUES ($1)" , [email]);
} catch (error) {
if (error instanceof DatabaseError ) {
switch (error.code ) {
case "23505" :
console .error ("Duplicate entry:" , error.detail );
break ;
case "23503" :
console .error ("Foreign key constraint failed:" , error.detail );
break ;
case "42P01" :
console .error ("Table does not exist:" , error.message );
break ;
case "28P01" :
console .error ("Authentication failed" );
break ;
case "57P03" :
console .error ("Server unavailable, retry later" );
break ;
default :
console .error (`PostgreSQL error ${error.code} : ${error.message} ` );
}
}
throw error;
}
Connection String Format
const pool = new Pool ({
connectionString : `postgres://${user} :${password} @${host} :${port} /${database} ?sslmode=require`
});
const connectionString =
`postgres://user:password@server.postgres.database.azure.com:5432/mydb?sslmode=require` ;
Pool Events const pool = new Pool ({ });
pool.on ("connect" , (client ) => {
console .log ("New client connected to pool" );
});
pool.on ("acquire" , (client ) => {
console .log ("Client checked out from pool" );
});
pool.on ("release" , (err, client ) => {
console .log ("Client returned to pool" );
});
pool.on ("remove" , (client ) => {
console .log ("Client removed from pool" );
});
pool.on ("error" , (err, client ) => {
console .error ("Unexpected pool error:" , err);
});
Azure-Specific Configuration Setting Value Description ssl.rejectUnauthorizedtrueAlways use SSL for Azure Default port 5432Standard PostgreSQL port PgBouncer port 6432Use when PgBouncer enabled Token scope https://ossrdbms-aad.database.windows.net/.defaultEntra ID token scope Token lifetime ~1 hour Refresh before expiry
Pool Sizing Guidelines Workload maxidleTimeoutMillisLight (dev/test) 5-10 30000 Medium (production) 20-30 30000 Heavy (high concurrency) 50-100 10000
Note : Azure PostgreSQL has connection limits based on SKU. Check your tier's max connections.
Best Practices
Always use connection pools for production applications
Use parameterized queries - Never concatenate user input
Always close connections - Use try/finally or connection pools
Enable SSL - Required for Azure (ssl: { rejectUnauthorized: true })
Handle token refresh - Entra ID tokens expire after ~1 hour
Set connection timeouts - Avoid hanging on network issues
Use transactions - For multi-statement operations
Monitor pool metrics - Track pool.totalCount, pool.idleCount, pool.waitingCount
Graceful shutdown - Call pool.end() on application termination
Use TypeScript generics - Type your query results for safety
Key Types import {
Client ,
Pool ,
PoolClient ,
PoolConfig ,
QueryResult ,
QueryResultRow ,
DatabaseError ,
QueryConfig
} from "pg" ;
Reference Links
When to Use This skill is applicable to execute the workflow or actions described in the overview.
Connections
Domain: [[Cloud & Infrastruktur]]
Kategorie: [[Microsoft Azure]]
Navigation: [[Skills Uebersicht]], [[Home]]