node-postgres创建数据库

时间:2013-12-28 09:50:48

标签: node.js postgresql

我正在使用node-postgres,在我的应用程序开始时,我想检查数据库是否存在。所以我的工作流程理念如下:

  1. 检查myDb是否存在
  2. 如果有,请创建表格
  3. 如果没有,则首先创建数据库,然后创建表
  4. 但是,如您所见,这是一个非常简单的过程,驱动程序实现需要连接数据库名postgres://username:password@host/database,这意味着您需要首先连接到数据库。

    所以我现在正在做的是在开始时连接到postgres数据库,进行查询以创建数据库,如果已经存在异常,则关闭异常,然后关闭我的连接并连接到新创建的数据库,然后创建表格。这是代码:

    var conStringPri = 'postgres://' + username + ':' + password + '@' + host + 
        '/postgres';
    var conStringPost = 'postgres://' + username + ':' + password + '@' + host + 
        '/' + dbName;
    
    pg.connect(conStringPri, function(err, client, done) { // connect to postgres db
        if (err)
            console.log('Error while connecting: ' + err); 
        client.query('CREATE DATABASE ' + dbName, function(err) { // create user's db
            if (err) 
                console.log('ignoring the error'); // ignore if the db is there
            client.end(); // close the connection
    
            // create a new connection to the new db
            pg.connect(conStringPost, function(err, clientOrg, done) {
                // create the table
                clientOrg.query('CREATE TABLE IF NOT EXISTS ' + tableName + ' ' +
                        '(...some sql...)';
            });
        });
    });
    

    如你所见,我两次打开和关闭连接,这种方式对我来说似乎不对。如果你提出一个更好的方法,我会很高兴,或者解释你是如何做到的。

4 个答案:

答案 0 :(得分:13)

  

然而,正如您所看到的,这是一个非常简单的过程   实现需要具有数据库名称   postgres:// username:password @ host / database to connected,which   意味着您需要先连接到数据库。

这不是因为驱动程序的实现,而是PostgreSQL本身。它与任何其他语言或驱动程序相同。

客户端需要连接到数据库才能执行任何操作,包括CREATE DATABASE。除postgres数据库外,template1通常也用于此目的。

然后,由于您必须连接到新创建的数据库以在其中创建对象,因此无法避免打开另一个连接。

简而言之,你所做的事情不能简化,它已经是最优的。

答案 1 :(得分:7)

我刚刚写了一个模块:https://github.com/olalonde/pgtools

var pgtools = require('pgtools');
pgtools.createdb({
  user: 'postgres',
  password: 'some pass',
  port: 5432,
  host: 'localhost'
}, 'test-db', function (err, res) {
  if (err) {
    console.error(err);
    process.exit(-1);
  }
  console.log(res);
});

希望它可以使你的代码更清洁。

答案 2 :(得分:3)

这有点旧,但我只是想分享一下我是如何处理这种设置的。

你需要从回调中调用第三个参数,即done中的pg.connect(conn, (err, client, done) => {})。这将释放连接并重新启动池。

 async.series([
   done => {
     pg.connect(connPrimary, (err, client, releaseConn) => {
      if (err) return done(err)

      client.query(`CREATE DATABASE ${conf.database}`, (err) => {
        if (err && !~err.message.indexOf('already exists')) {
          return done(err)
        }

        client.end()
        releaseConn()
        done()
      })
    })
  },
  done => {
    let connSecondary = `postgres://${conf.user}:${conf.password}@${conf.host}:${conf.port}/${conf.database}`

    pg.connect(connSecondary, (err, client, releaseConn) => {
      if (err) return done(err)

      let createTableQuery = `CREATE TABLE IF NOT EXISTS test_table(_id bigint primary key, co2_field varchar(40) NOT NULL, temp_field int NOT NULL, quality_field decimal NOT NULL, reading_time_field timestamp NULL)`

      client.query(createTableQuery, err => {
        if (err) return done(err)

        releaseConn()
        done()
      })
    })    
  }
], err => {
  should.ifError(err)
  doneInit()
})

答案 3 :(得分:0)

安装

npm install --save -g pgtools

CLI示例

createdbjs my_awesome_db --user=admin --password=admin