我在用Node.js的 PostgreSQL库动态创建表。如何正确处理列类型名的SQL片段,比如boolean?

后端开发 2026-07-11

我正在尝试使用 Postgres npm库 来动态创建表,如下所示:

const table = {
    schema: 'public',
    name: 'test',
    columns: [
       {name: 'id', type: 'uuid', pk: true},
       {name: 'exists', type: 'boolean', pk: false}
    ]
}

await sql`create table if not exists ${sql(table.schema)}.${sql(table.name)} (${
    table.columns.flatMap((column, index) =>
        [
            index ? sql`,` : sql``,
            sql`${sql(column.name)} ${sql(column.type)} ${column.pk ? sql`primary key` : sql``}`,
        ]
)})`;

我在自述文件中的 动态排序示例 里跟着做。问题在于我还没想清楚如何以可行的方式传递 column.type

  • ${sql(column.type)} 在运行时会产生带引号的文本,这对原始类型来说不工作。

ERROR: type "boolean" does not exist at character 82
STATEMENT: create table if not exists "public"."test" ( "id" "uuid" primary key , "exists" "boolean" ) * ${column.name} 的结果是在PostgreSQL不期望的位置使用了占位符。

ERROR: syntax error at or near "$1" at character 52
STATEMENT: create table if not exists "public"."test" ("id" $1 primary key, "exists" $2) * 试图将类型作为简单字符串传递,即 [...}, column.type, ${...],会导致库抛出错误,因为它期望所有内容都是SQL片段,而不是字符串。

有没有办法用这个库来实现?我需要使用 sql.unsafe 吗,然后再手动对查询进行清理?

解决方案

尝试使用FORMAT() 函数来正确对动态值进行引号处理

SELECT
  FORMAT('Hello, %s', 'David');
  • %s:将参数格式化为简单字符串。
  • %I:将参数格式化为一个SQL标识符(例如表名或列名),并使用正确的双引号。这等价于 quote_ident()
  • %L:将参数格式化为一个SQL字面量(例如在 WHERE 子句中的值),并使用正确的单引号。这与 quote_literal() 等价。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章