Loading...
Loading...
Compare original and translation side by side
psqlpsqlscripts/psql-connect.shtenant_idpsqlaws dsql generate-db-connect-auth-tokenpsqlpsqlscripts/psql-connect.shtenant_idaws dsql generate-db-connect-auth-tokenpsqlpsqlscripts/psql-connect.shpsqlpsqlscripts/psql-connect.shpsqlpsqlpsqlaws___search_documentationaws___read_documentationaws___recommendaws___retrieve_skillaws___list_regionsaws___get_regional_availabilityaws___call_awsaws___run_scriptaws___get_tasksaws___get_presigned_urlaws___search_documentationaws___read_documentationaws___recommendaws___retrieve_skillaws___list_regionsaws___get_regional_availabilityaws___call_awsaws___run_scriptaws___get_tasksaws___get_presigned_urlexample_preferred.<ext>language.mdimport aurora_dsql_psycopg as dsqldsql.connect(host, region, user)import { AuroraDSQLPool } from "@aws/aurora-dsql-node-postgres-connector"new AuroraDSQLPool({ host, user })import { auroraDSQLPostgres } from "@aws/aurora-dsql-postgresjs-connector"auroraDSQLPostgres({ host, user })import "github.com/awslabs/aurora-dsql-connectors/go/pgx/dsql"software.amazon.dsql:aurora-dsql-jdbc-connector:1.4.0jdbc:aws-dsql:postgresql://...example_preferred.<ext>language.mdimport aurora_dsql_psycopg as dsqldsql.connect(host, region, user)import { AuroraDSQLPool } from "@aws/aurora-dsql-node-postgres-connector"new AuroraDSQLPool({ host, user })import { auroraDSQLPostgres } from "@aws/aurora-dsql-postgresjs-connector"auroraDSQLPostgres({ host, user })import "github.com/awslabs/aurora-dsql-connectors/go/pgx/dsql"software.amazon.dsql:aurora-dsql-jdbc-connector:1.4.0jdbc:aws-dsql:postgresql://...dsql:DbConnectdsql:DbConnectpsqlpsqlexamples/*.mdexamples/*.mdpsqlscripts/psql-connect.shpsql./scripts/psql-connect.sh --cluster <cluster-id> --command "SELECT * FROM entities LIMIT 10"./scripts/psql-connect.sh --cluster <cluster-id> --admin --command "CREATE INDEX ASYNC ..."list_tablesSELECT table_name FROM information_schema.tables WHERE table_schema = 'public';psqlscripts/psql-connect.shpsql./scripts/psql-connect.sh --cluster <cluster-id> --command "SELECT * FROM entities LIMIT 10"./scripts/psql-connect.sh --cluster <cluster-id> --admin --command "CREATE INDEX ASYNC ..."list_tablesSELECT table_name FROM information_schema.tables WHERE table_schema = 'public';aws___search_documentationaws___read_documentation| Limit | Default | Verify query |
|---|---|---|
| Max rows mutated per transaction | 3,000 | |
| Max data modified per write transaction | 10 MiB | |
| Max transaction duration | 5 minutes | |
| Max connections per cluster | 10,000 | |
| IAM auth token expiry | 15 minutes | |
| Max connection duration | 60 minutes | |
| Max indexes per table | 24 | |
| Max columns per index | 8 | |
| IDENTITY/SEQUENCE CACHE values | 1 or >= 65536 | |
aws___search_documentationaws___read_documentation| 限制项 | 默认值 | 验证查询语句 |
|---|---|---|
| 每个事务可修改的最大行数 | 3,000 | |
| 每个写入事务可修改的最大数据量 | 10 MiB | |
| 最长事务时长 | 5分钟 | |
| 每个集群的最大连接数 | 10,000 | |
| IAM认证令牌有效期 | 15分钟 | |
| 最长连接时长 | 60分钟 | |
| 每个表的最大索引数 | 24 | |
| 每个索引的最大列数 | 8 | |
| IDENTITY/SEQUENCE缓存值 | 1或≥65536 | |
psqlscripts/create-cluster.shCreateCluster| Task | Script | Example |
|---|---|---|
| Create cluster with tags | | |
| List clusters | | |
| Inspect cluster | | |
| Connect via psql | | |
psqlscripts/create-cluster.shCreateCluster| 任务 | 脚本 | 示例 |
|---|---|---|
| 创建带标签的集群 | | |
| 列出集群 | | |
| 查看集群信息 | | |
| 通过psql连接 | | |
./scripts/psql-connect.sh --cluster <id> --command "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"
./scripts/psql-connect.sh --cluster <id> --command "SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '<table>' ORDER BY ordinal_position"./scripts/psql-connect.sh --cluster <id> --command "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"
./scripts/psql-connect.sh --cluster <id> --command "SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_schema = 'public' AND table_name = '<table>' ORDER BY ordinal_position"Use psql-connect.sh (or the language connector in app code) for SELECT queries
Always include tenant_id in WHERE clause for multi-tenant apps
MUST build SQL with safe_query.build() — see references/input-validation.md使用psql-connect.sh(或应用代码中的语言连接器)执行SELECT查询
多租户应用必须在WHERE子句中包含tenant_id
必须使用safe_query.build()构建SQL——参见references/input-validation.mdUse ./scripts/psql-connect.sh --admin (or the language connector with the IAM admin auth token) for DDL
Follow one-DDL-per-transaction rule
Always use CREATE INDEX ASYNC in a separate statement
ALTER COLUMN TYPE, DROP COLUMN, DROP CONSTRAINT → Table Recreation Pattern (Workflow 6)使用./scripts/psql-connect.sh --admin(或带IAM管理员认证令牌的语言连接器)执行DDL
遵循每个事务一条DDL的规则
始终在单独语句中使用CREATE INDEX ASYNC
ALTER COLUMN TYPE、DROP COLUMN、DROP CONSTRAINT → 使用表重建模式(工作流6)psqlaws dsql generate-db-connect-auth-tokengenerate-db-connect-admin-auth-tokenpsqlaws dsql generate-db-connect-auth-tokengenerate-db-connect-admin-auth-tokenaws dsql./scripts/create-cluster.sh --created-by <model-id> --tags Environment=eval,Project=dsql-skill-eval./scripts/cluster-info.sh <cluster-id>./scripts/delete-cluster.sh <cluster-id> [--force] # --force skips the confirmation prompt in non-TTYaws___call_aws{"service": "dsql", "operation": "CreateCluster",
"parameters": {"tags": {"created_by": "<model-id>", "Environment": "eval", "Project": "dsql-skill-eval"}, "deletionProtectionEnabled": true}}{"service": "dsql", "operation": "GetCluster", "parameters": {"identifier": "<cluster-id>"}}{"service": "dsql", "operation": "DeleteCluster", "parameters": {"identifier": "<cluster-id>"}}CreateClusterDeleteClusterstatusCREATINGDELETINGaws___call_awsdsql:GetCluster.status == "ACTIVE"aws___get_tasksaws dsqlaws dsql./scripts/create-cluster.sh --created-by <model-id> --tags Environment=eval,Project=dsql-skill-eval./scripts/cluster-info.sh <cluster-id>./scripts/delete-cluster.sh <cluster-id> [--force] # --force在非TTY环境下跳过确认提示aws___call_aws{"service": "dsql", "operation": "CreateCluster",
"parameters": {"tags": {"created_by": "<model-id>", "Environment": "eval", "Project": "dsql-skill-eval"}, "deletionProtectionEnabled": true}}{"service": "dsql", "operation": "GetCluster", "parameters": {"identifier": "<cluster-id>"}}{"service": "dsql", "operation": "DeleteCluster", "parameters": {"identifier": "<cluster-id>"}}CreateClusterDeleteClusterstatusCREATINGDELETINGaws___call_awsdsql:GetCluster.status == "ACTIVE"aws___get_tasksaws dsqlpgpsycopgpgxtokio-postgresaurora-dsql-python-connector@aws/aurora-dsql-node-postgres-connector@aws/aurora-dsql-postgresjs-connectorgithub.com/awslabs/aurora-dsql-connectors/go/pgxsoftware.amazon.dsql:aurora-dsql-jdbc-connectoraurora-dsql-sqlx-connectorpgpsycopgpgxtokio-postgresaurora-dsql-python-connector@aws/aurora-dsql-node-postgres-connector@aws/aurora-dsql-postgresjs-connectorgithub.com/awslabs/aurora-dsql-connectors/go/pgxsoftware.amazon.dsql:aurora-dsql-jdbc-connectoraurora-dsql-sqlx-connectortenant_idCREATE INDEX ASYNCtenant_idCREATE INDEX ASYNCsafe_query.build()safe_query.build()safe_query.build()allow()regex()'v'ident()"v"tenant_idsafe_query.build()allow()regex()'v'ident()"v"tenant_idpsql -c "..."safe_query.build()psql -csafe_querysafe_query| Value kind | Validator | Emits |
|---|---|---|
| Known set (tenant ID, status enum) | | |
| Known set used as SQL keyword (ASC/DESC) | | |
| Strict format (UUID, slug, ISO date) | | |
| Table or column name | | |
| Integer | | |
| Free text (description, comment, user name) | | |
safe_query.pyTENANT_SLUG[a-z0-9-]{1,64}UUIDINTISO_DATEfrom safe_query import build, allow, regex, ident, keyword, integer, literal, UnsafeSQLError
from safe_query import TENANT_SLUG, UUID, ISO_DATEregex(req.tenant, TENANT_SLUG)allow(req.tenant, ALLOWED_TENANTS)safe_query.build().format()sql = build(
"SELECT * FROM {t} WHERE tenant_id = {tid}",
t=ident("entities"),
tid=regex(req.tenant, TENANT_SLUG),
)psql -c "..."safe_query.build()psql -csafe_querysafe_query| 值类型 | 验证器 | 输出格式 |
|---|---|---|
| 已知集合(租户ID、状态枚举) | | |
| 用作SQL关键字的已知集合(ASC/DESC) | | |
| 严格格式(UUID、短标识、ISO日期) | | |
| 表或列名 | | |
| 整数 | | |
| 自由文本(描述、评论、用户名) | | |
safe_query.pyTENANT_SLUG[a-z0-9-]{1,64}UUIDINTISO_DATEfrom safe_query import build, allow, regex, ident, keyword, integer, literal, UnsafeSQLError
from safe_query import TENANT_SLUG, UUID, ISO_DATEregex(req.tenant, TENANT_SLUG)allow(req.tenant, ALLOWED_TENANTS)safe_query.build().format()sql = build(
"SELECT * FROM {t} WHERE tenant_id = {tid}",
t=ident("entities"),
tid=regex(req.tenant, TENANT_SLUG),
)sqlsqlsqlsql
**Rubric-Critical Scenario 2 — batch INSERT with UUIDs, slugs, and free text.** Each row's INSERT is built separately with `safe_query.build()`: `entity_id` via `regex(..., UUID)`, `tenant_id` via `regex(..., TENANT_SLUG)`, description via `literal(...)` (dollar-quoted to sidestep quote escaping). Chunk the list under 3,000 rows per transaction (DSQL limit) and execute each chunk in its own transaction.
```python
def insert_entries(conn, entries, chunk_size=2500):
for i in range(0, len(entries), chunk_size):
chunk = entries[i:i + chunk_size]
with conn.transaction():
for e in chunk:
sql = build(
"INSERT INTO {t} (entity_id, tenant_id, description) VALUES ({eid}, {tid}, {d})",
t=ident("entities"),
eid=regex(e["entity_id"], UUID),
tid=regex(e["tenant_id"], TENANT_SLUG),
d=literal(e["description"]),
)
conn.execute(sql)safe_query.build()regex(tenant_id, TENANT_SLUG)allow(status, {'active','archived','deleted'})regex(..., ISO_DATE)sql = build(
"UPDATE {t} SET status = {s} WHERE tenant_id = {tid} AND created_at < {d}",
t=ident("entities"),
s=allow(req.status, {"active", "archived", "deleted"}),
tid=regex(req.tenant, TENANT_SLUG),
d=regex(req.date, ISO_DATE),
)
conn.execute(sql)sort_col{'created_at','updated_at','name'}ident()sort_dirkeyword(){'ASC','DESC'}ASCtenant_idregex()allow()regex()ident()ALLOWED_SORT_COLS = {"created_at", "updated_at", "name"}
if sort_col not in ALLOWED_SORT_COLS:
raise ValueError(f"sort_col must be one of {ALLOWED_SORT_COLS}")
sql = build(
"SELECT * FROM {t} WHERE tenant_id = {tid} ORDER BY {col} {dir}",
t=ident("entities"),
tid=regex(req.tenant, TENANT_SLUG),
col=ident(sort_col),
dir=keyword(req.sort_dir, {"ASC", "DESC"}),
)safe_query.build()safe_query.build() + regex(..., UUID)undefined
**关键场景2——包含UUID、短标识和自由文本的批量INSERT。** 每行INSERT单独使用`safe_query.build()`构建:`entity_id`使用`regex(..., UUID)`,`tenant_id`使用`regex(..., TENANT_SLUG)`,描述使用`literal(...)`(美元引号避免转义问题)。将列表拆分为每个事务不超过3000行(DSQL限制),并在单独事务中执行每个批次。
```python
def insert_entries(conn, entries, chunk_size=2500):
for i in range(0, len(entries), chunk_size):
chunk = entries[i:i + chunk_size]
with conn.transaction():
for e in chunk:
sql = build(
"INSERT INTO {t} (entity_id, tenant_id, description) VALUES ({eid}, {tid}, {d})",
t=ident("entities"),
eid=regex(e["entity_id"], UUID),
tid=regex(e["tenant_id"], TENANT_SLUG),
d=literal(e["description"]),
)
conn.execute(sql)safe_query.build()regex(tenant_id, TENANT_SLUG)allow(status, {'active','archived','deleted'})regex(..., ISO_DATE)sql = build(
"UPDATE {t} SET status = {s} WHERE tenant_id = {tid} AND created_at < {d}",
t=ident("entities"),
s=allow(req.status, {"active", "archived", "deleted"}),
tid=regex(req.tenant, TENANT_SLUG),
d=regex(req.date, ISO_DATE),
)
conn.execute(sql)sort_col{'created_at','updated_at','name'}ident()sort_dirkeyword(){'ASC','DESC'}ASCtenant_idregex()allow()regex()ident()ALLOWED_SORT_COLS = {"created_at", "updated_at", "name"}
if sort_col not in ALLOWED_SORT_COLS:
raise ValueError(f"sort_col必须是{ALLOWED_SORT_COLS}之一")
sql = build(
"SELECT * FROM {t} WHERE tenant_id = {tid} ORDER BY {col} {dir}",
t=ident("entities"),
tid=regex(req.tenant, TENANT_SLUG),
col=ident(sort_col),
dir=keyword(req.sort_dir, {"ASC", "DESC"}),
)safe_query.build()safe_query.build() + regex(..., UUID)undefined
**Anti-patterns (the rubric fails these):**
- Using f-strings, `.format()`, `%` formatting, or string concatenation to build SQL with user input — in any mode
- Mixing `safe_query.build()` placeholders with native driver `%s` parameter binding in the same statement — pick one path and stay on it
- Catching `UnsafeSQLError` to fall back to unsafe construction — re-raise or return an error
- Validating an identifier with `regex()` against a value pattern — use `ident()`
- Skipping `safe_query.build()` in read-only mode under "the value is already validated upstream" — defense in depth means the SQL builder validates independently of upstream
**反模式(不符合规范):**
- 使用f-strings、`.format()`、`%`格式化或字符串拼接构建包含用户输入的SQL——任何模式下都禁止
- 在同一条语句中混合使用`safe_query.build()`占位符和驱动原生`%s`参数绑定——选择一种方式并坚持使用
- 捕获`UnsafeSQLError`后回退到不安全构建方式——应重新抛出或返回错误
- 使用`regex()`并匹配值模式验证标识符——使用`ident()`
- 在只读模式下以“值已在上游验证”为由跳过`safe_query.build()`——深度防御要求SQL构建器独立于上游进行验证ALTER COLUMN TYPEDROP COLUMNDROP CONSTRAINTMODIFY PRIMARY KEYALTER COLUMN TYPEDROP COLUMNDROP CONSTRAINTMODIFY PRIMARY KEY>30sEXPLAIN ANALYZE VERBOSEpsqlpg_classpg_statspg_indexesCOUNT(*)COUNT(DISTINCT)catalog-queries.mdplan-interpretation.mdguc-experiments.mdreport-format.md./scripts/psql-connect.sh --cluster <id> --command "EXPLAIN ANALYZE VERBOSE <sql>"
./scripts/psql-connect.sh --cluster <id> --script ./experiment-2.sql # GUC multi-statement>30spsqlEXPLAIN ANALYZE VERBOSEcatalog-queries.mdpg_classpg_statspg_indexesCOUNT(*)COUNT(DISTINCT)plan-interpretation.mdguc-experiments.mdreport-format.md./scripts/psql-connect.sh --cluster <id> --command "EXPLAIN ANALYZE VERBOSE <sql>"
./scripts/psql-connect.sh --cluster <id> --script ./experiment-2.sql # GUC多语句dsql:DbConnectadmindsql:DbConnectAdminsslmode=verify-fullpsql-connect.shrequiresafe_query.build()safe_query.build()allowregexidentkeywordintegerliteral.format()tenant_idtenant_idtenant_iddsql:DbConnectadmindsql:DbConnectAdminsslmode=verify-fullpsql-connect.shrequiresafe_query.build()safe_query.build()allowregexidentkeywordintegerliteral.format()tenant_idtenant_idtenant_idaws-database-selectionrequirements.jsonaws_dbs_requirements/*/requirements.jsonaws-database-selection/references/handoff-contract.mdfile_readaws-database-selection/references/workload-primary-artifact.schema.jsonworkload_primaries.dominant_shapesmigration_contextamazon-aurorards-ossaws-database-selectionaws-database-selectionrequirements.jsonaws_dbs_requirements/*/requirements.jsonaws-database-selection/references/handoff-contract.mdfile_readaws-database-selection/references/workload-primary-artifact.schema.jsonworkload_primaries.dominant_shapesmigration_contextamazon-aurorards-ossaws-database-selection