我尝试使用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。
答案 0 :(得分:35)
好的,通过浏览sequelize源代码找到了答案: https://github.com/sequelize/sequelize/blob/master/lib/dialects/postgres/connection-manager.js#L39
要为PG连接激活SSL,您不需要native: true
或ssl: 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)
你只需要这两件事
?sslmode=require
附加到您的 POSTGRES 数据库 URIrejectUnauthorized: 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 。
这就是您需要知道的一切。