【问题标题】:Can't connect to heroku postgresql database from local node app with sequelize无法使用 sequelize 从本地节点应用程序连接到 heroku postgresql 数据库
【发布时间】:2015-02-25 13:28:12
【问题描述】:

我正在尝试使用 Sequelize 从本地 nodejs 应用程序连接到 Heroku postgresql 数据库。我遵循了这两个指南,在 heroky 服务器端一切正常,但是当我在 Mac 上本地运行节点应用程序时,它无法连接到 heroku。

这是我启动本地应用程序的方式:

DATABASE_URL=$(heroku config:get DATABASE_URL) nodemon

得到我:

Sequelize: Unable to connect to the database:

但我通过这样做得到了正确的 URL:

echo $(heroku config:get DATABASE_URL)

这些命令运行良好:

heroku pg:psql
psql $(heroku config:get DATABASE_URL)

这是我的 nodejs 代码:

var match = process.env.DATABASE_URL.match(/postgres:\/\/([^:]+):([^@]+)@([^:]+):(\d+)\/(.+)/)
sequelize = new Sequelize(match[5], match[1], match[2], {
    dialect:  'postgres',
    protocol: 'postgres',
    port:     match[4],
    host:     match[3],
    logging: false
})

sequelize
.authenticate()
.complete(function(err) {
    if (!!err) {
        log('Sequelize: Unable to connect to the database:', err);
    } else {
        http.listen(process.env.PORT || config.server.port, function(){
            log('Web server listening on port '+process.env.PORT || config.server.port);
        });
    }
});

我尝试将native: true 添加到续集选项中,但随后我得到:

    /Users/clement/Projets/XMM/node_modules/sequelize/lib/sequelize.js:188
      throw new Error('The dialect ' + this.getDialect() + ' is not supported.
            ^
Error: The dialect postgres is not supported. (Error: Please install postgres package manually)
    at new module.exports.Sequelize (/Users/clement/Projets/XMM/node_modules/sequelize/lib/sequelize.js:188:13)
    at Object.<anonymous> (/Users/clement/Projets/XMM/server.js:17:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Function.Module.runMain (module.js:497:10)
    at startup (node.js:119:16)
    at node.js:929:3

即使做了之后:

npm install pg
npm install -g pg
brew install postgresql

顺便说一句,这是可行的:

var pg = require('pg');
pg.connect(process.env.DATABASE_URL+'?ssl=true', function(err, client, done) {
    if (err) return console.log(err);
    client.query('SELECT * FROM pg_catalog.pg_tables', function(err, result) {
        done();
        if(err) return console.error(err);
        console.log(result.rows);
    });
});

但我宁愿使用 Sequelize。

【问题讨论】:

标签: node.js postgresql heroku sequelize.js heroku-postgres


【解决方案1】:

好的,通过浏览sequelize源码找到了答案: https://github.com/sequelize/sequelize/blob/master/lib/dialects/postgres/connection-manager.js#L39

要为 PG 连接激活 SSL,您不需要 native: truessl: true,而是需要 dialectOptions.ssl: true,因此以下方法终于奏效了:

sequelize = new Sequelize(process.env.DATABASE_URL, {
    dialect: 'postgres',
    protocol: 'postgres',
    dialectOptions: {
        ssl: true
    }
});

要解决SequelizeConnectionError: self signed certificate 中提到的node-postgres 版本8 上的self signed certificate 错误,您可以改用:

sequelize = new Sequelize(process.env.DATABASE_URL, {
    dialect: 'postgres',
    protocol: 'postgres',
    dialectOptions: {
        ssl: {
            require: true,
            rejectUnauthorized: false
        }
    }
});

【讨论】:

  • 谢谢!这让我花了很长时间才弄清楚。网上其他地方有不好的说明(也试图使用本机)。重要的是要注意,sequelize 的错误消息很糟糕(实际错误不在顶部)——所以如果你得到一个方言不支持的消息看起来有点低......在我的情况下,pg-hstore 丢失并且需要已安装。
  • 谢谢。也许这是一个超级菜鸟问题——我在服务器上将ssl 选项设置为true,我已经在客户端上添加了这个。连接正常。是这样吗?我需要做任何其他事情来启用 SSL 吗?非常感谢
  • 嗨,克里斯,我无法回答您的问题,并且由于它与此处讨论的主题没有直接关系,我认为您应该在 stackoverflow 上创建一个全新的问题以获得帮助。
  • 天哪,我在这个错误上花了 3 个小时。非常感谢!
  • 要修复self signed certificate错误,请参考这篇文章:stackoverflow.com/questions/58965011/…
【解决方案2】:

您不再需要解析 DATABASE_URL 环境变量,有一个接受连接 URL 的 Sequelize 构造函数:

sequelize = new Sequelize(process.env.DATABASE_URL, {
    dialect: 'postgres',
    protocol: 'postgres',
    dialectOptions: {
        ssl: true
    }
});

【讨论】:

  • 你已经回答了你自己的问题(dialectOptions.ssl: true),我只是在它的基础上提供了一个更简单的解决方案
【解决方案3】:

需要在ssl下添加dialectOptions

 "development": {
    "username": process.env.DB_USERNAME,
    "password": process.env.DB_PASSWORD,
    "database": process.env.DB_NAME,
    "host": process.env.DB_HOST,
    "dialect": process.env.DB_DIALECT,
    "dialectOptions": {
        ssl: {
            require: true,
            rejectUnauthorized: false
        }
    }
},

来源为官方sequelize github

【讨论】:

【解决方案4】:

你只需要这两件事

  1. ?sslmode=require 附加到您的 POSTGRES 数据库 URI
  2. 确保您的dialectOptions 中有rejectUnauthorized: false
const sequelize = new Sequelize(`${process.env.DATABASE_URI}?sslmode=require`, {
  url: process.env.DATABASE_URI,
  dialect: 'postgres',
  logging: false,
  dialectOptions: {
    ssl: {
      require: true,
      rejectUnauthorized: false, // very important
    }
  }
}

有关更多信息,请参阅 Heroku DevCenter 上的一篇文章
https://devcenter.heroku.com/articles/heroku-postgresql#heroku-postgres-ssl

【讨论】:

    【解决方案5】:

    我遇到了同样的问题,对于这些情况,您可以考虑以下有关如何连接 heroku 数据库的文档示例:

    https://sequelize.readthedocs.io/en/1.7.0/articles/heroku/

    最后我确实实现了如下代码:

    const sequelize = new Sequelize(
        process.env.DATABASE_NAME_DB_CONFIG,
        process.env.USER_NAME_DB_CONFIG,
        process.env.USER_PASSWORD_DB_CONFIG,
        {
            host: process.env.HOST_DB_CONFIG,
            dialect: process.env.DIALECT_DB_CONFIG,
            protocol: process.env.PROTOCOL_DB_CONFIG,
            logging:  true,
            dialectOptions: {
                ssl: true
            },
            pool: {
                max: 5,
                min: 0,
                idle: 10000
            }
        }
    );
    

    您需要在哪里考虑到ssl: truedialectOptions

    这就是你需要知道的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-26
      • 2021-09-25
      • 1970-01-01
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 2020-05-30
      • 1970-01-01
      相关资源
      最近更新 更多