【问题标题】:How to set schema with node-postgres如何使用 node-postgres 设置架构
【发布时间】:2019-10-09 06:06:39
【问题描述】:

我正在尝试使用 node-postgres 在我的 postgres 数据库中查询名为 DOCUMENT 的架构。

我似乎无法获得针对指定架构运行的查询。

这个查询使用 psql 直接针对 postgres 运行良好

SELECT * FROM "DOCUMENT".document_metadata m 
LEFT OUTER JOIN "DOCUMENT".document_attributes a 
ON a.document_id = m.id

此代码产生以下错误

const query = `SELECT * FROM "DOCUMENT".document_metadata m 
               LEFT OUTER JOIN "DOCUMENT".document_attributes a 
               ON a.document_id = m.id`
const metadata = await db.query(query)

错误

error: relation "DOCUMENT.document_metadata" does not exist
    at Connection.parseE (/usr/src/app/node_modules/pg/lib/connection.js:602:11)
    at Connection.parseMessage (/usr/src/app/node_modules/pg/lib/connection.js:399:19)
    at Socket.<anonymous> (/usr/src/app/node_modules/pg/lib/connection.js:121:22)
    at Socket.emit (events.js:189:13)
    at addChunk (_stream_readable.js:284:12)
    at readableAddChunk (_stream_readable.js:265:11)
    at Socket.Readable.push (_stream_readable.js:220:10)
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)

我也试过了

const query = `SET search_path TO 'DOCUMENT';
               SELECT * FROM document_metadata m 
               LEFT OUTER JOIN document_attributes a 
               ON a.document_id = m.id;`

const metadata = await db.query(query)

产生错误

error: relation "document_metadata" does not exist
    at Connection.parseE (/usr/src/app/node_modules/pg/lib/connection.js:602:11)
    at Connection.parseMessage (/usr/src/app/node_modules/pg/lib/connection.js:399:19)
    at Socket.<anonymous> (/usr/src/app/node_modules/pg/lib/connection.js:121:22)
    at Socket.emit (events.js:189:13)
    at addChunk (_stream_readable.js:284:12)
    at readableAddChunk (_stream_readable.js:265:11)
    at Socket.Readable.push (_stream_readable.js:220:10)
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)

更新 当我直接在 psql 中运行这些相同的查询时,我看到 10 行带有表名。当我通过我的节点代码运行它时,我看不到任何行:

const metadata4 = await db.query('SHOW search_path;')
console.log('search_path after setting = ', metadata4.rows) // prints [ { search_path: '"DOCUMENT"' } ]

const tables = await db.query(`SELECT * FROM information_schema.tables where table_schema = 'DOCUMENT';`)
console.log('tables = ', tables.rows) // prints []

【问题讨论】:

    标签: javascript node.js postgresql node-postgres


    【解决方案1】:

    只需在单独的行中执行:

    db.query("SET search_path TO 'DOCUMENT';")
    

    DOCUMENT 是你的模式的名称,然后执行普通查询:

    const query = `SELECT * FROM document_metadata m 
                   LEFT OUTER JOIN document_attributes a 
                   ON a.document_id = m.id;`
    
    db.query(query)
    

    【讨论】:

    • 刚试了下,还是报表不存在的错误:/
    • @VincentBuscarello 也许你的用户权限有问题?
    • 不,如果我硬编码架构名称,我可以运行查询,但我试图动态地将架构名称传递给查询。 stackoverflow.com/questions/62907228/…
    【解决方案2】:

    也许大写是问题所在。 您是否尝试过使用小写模式名称? 或者在表名两边加引号:

    const query = 'SELECT * FROM "DOCUMENT"."document_metadata" m 
                   LEFT OUTER JOIN "DOCUMENT"."document_attributes" a 
                   ON a.document_id = m.id'
    

    在客户端/池的环境变量中定义架构

    无论如何,如果你想在node js中定义schema,并且不需要在不同的schema之间切换,那么这个solution是一个不错的选择。 默认架构可以来自环境变量。

    const Pool = require('pg').Pool
    const Client = require('pg').Client
    
    class EnhancedClient extends Client {
      getStartupConf() {
        if (process.env.PG_OPTIONS) {
          try {
            const options = JSON.parse(process.env.PG_OPTIONS);
            return {
              ...super.getStartupConf(),
              ...options,
            };
          } catch (e) {
            console.error(e);
            // Coalesce to super.getStartupConf() on parse error
          }
        }
    
        return super.getStartupConf();
      }
    }
    
    const pool = new Pool({
      Client: EnhancedClient,
      user: 'postgres',
      host: 'localhost',
      database: 'postgres',
      password: 'postgres',
      port: 5432
    })
    

    在这个例子中,PG_OPTIONS 是字符串化的 JSON,例如通过命令行、PM2 生态系统文件等提供。

    例如:PG_OPTIONS='{"search_path":"DOCUMENT"}' node app.js

    我从 windows 命令提示符开始(对不起:))

    SET PG_OPTIONS={"search_path":"DOCUMENT"}
    node app.js
    

    【讨论】:

      【解决方案3】:

      当您创建数据库 URL 时,您可以像这样将架构附加到它:

      `postgres://${dbUser}:${dbPass}@${dbHost}:${dbPort}/${dbName}?schema=${schema}`
      

      【讨论】:

        猜你喜欢
        • 2012-06-17
        • 1970-01-01
        • 1970-01-01
        • 2021-09-18
        • 1970-01-01
        • 2013-03-28
        • 1970-01-01
        • 1970-01-01
        • 2016-03-18
        相关资源
        最近更新 更多