无法使用sequelize从本地节点应用程序连接到heroku postgresql数据库

时间:2014-12-29 10:58:41

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

我尝试使用Sequelize从本地nodejs应用程序连接到Heroku postgresql数据库。我按照这两个指南,一切都在myoky服务器端完美运行,但我的节点应用程序在我在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。

5 个答案:

答案 0 :(得分:35)

好的,通过浏览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
    }
});

答案 1 :(得分:13)

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

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

答案 2 :(得分:8)

需要在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
        }
    }
},

源码来自官方的续集 github

答案 3 :(得分:1)

你只需要这两件事

  1. ?sslmode=require 附加到您的 POSTGRES 数据库 URI
  2. 确保您的 rejectUnauthorized: false 中有 dialectOptions
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

答案 4 :(得分:0)

我遇到了同样的问题,对于这些情况,您可以考虑以下有关如何连接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: true中考虑 dialectOptions

这就是您需要知道的一切。