3

node.jsにnode-postgresモジュールを使用していますが、データの挿入に問題があります。

関数:

function addItems(listId, listItems, handle) {
    if (!listItems) {
        handle(listId);
        return;
    }
    var client = dbConnector.getClient(),
        important,
        dateArray,
        dateString,
        i,
        prepStatement;
    client.connect();
    for (i in listItems) {
        console.log(listItems[i]);
        dateArray = listItems[i].itemdate.split('-');
        dateString = dateArray[1] + '-' + dateArray[0] + '-' + dateArray[2];
        if (listItems[i].important) {
            important = 'true';
        } else {
            important = 'false';
        }
        prepStatement = {
            name: 'insert task',
            text: 'INSERT INTO listitem (todolist_id, name, deadline, description, important, done, created) VALUES ($1, $2, $3, $4, $5, $6, now()) RETURNING listitem_id',
            values: [ listId, listItems[i].itemname, dateString, listItems[i].itemdesc, important, listItems[i].done ]
        };
        var query = client.query(prepStatement);
        console.log("Adding item " + i);
        query.on('error', function(error) {
            console.log(error);
        });
        query.on('end', function(result) {
           console.log("Query ended");
           if (result) {
               console.log("Added listitem no " + result.rows[0].listitem_id);
           } 
        });
    }
    client.end();
    handle(listId);
}

データベースに新しいデータは表示されません。query.on('error')およびquery.on('end')イベントが発生することはありません。考えてみると、クエリがトリガーされているのかどうか疑問に思い始めています(なぜトリガーされるべきでないのかわかりません)。

私が取得する唯一のログは次のとおりです。

{  itemname: 'Task 1',
   itemdate: '08-05-2012',
   important: 'on',
   itemdesc: 'A task',
   done: 'false' }
Adding item 0
{  itemname: 'Task 2',
   itemdate: '22-05-2012',
   important: 'on',
   itemdesc: 'Another one',
   done: 'false' }
Adding item 1

では、これをデバッグするにはどうすればよいですか?

4

1 に答える 1

5

クエリを実行する前に client.end() を呼び出します。node-postgres は、接続の準備ができるまでクエリをキューに入れるように設計されているため、「接続されていません」というエラーをスローしません。 https://github.com/brianc/node-postgres/wiki/Client#method-connect

これを試して:

function addItems(listId, listItems, handle) {
    if (!listItems) {
        handle(listId);
        return;
    }
    var client = dbConnector.getClient(),
        important,
        dateArray,
        dateString,
        i, 
        prepStatement,
        queryCount = 0;
    client.connect();
    for (i in listItems) {
        console.log(listItems[i]);
        dateArray = listItems[i].itemdate.split('-');
        dateString = dateArray[1] + '-' + dateArray[0] + '-' + dateArray[2];
        if (listItems[i].important) {
            important = 'true';
        } else {
            important = 'false';
        }
        prepStatement = {
            name: 'insert task',
            text: 'INSERT INTO listitem (todolist_id, name, deadline, description, important, done, created) VALUES ($1, $2, $3, $4, $5, $6, now()) RETURNING listitem_id',
            values: [ listId, listItems[i].itemname, dateString, listItems[i].itemdesc, important, listItems[i].done ]
        };
        var query = client.query(prepStatement);
        queryCount++;
        console.log("Adding item " + i);
        query.on('error', function(error) {
            console.log(error);
        });
        query.on('end', function(result) {
           queryCount--;
           console.log("Query ended");
           if (result) {
               console.log("Added listitem no " + result.rows[0].listitem_id);
           } 
           if (queryCount === 0) {
             client.end();
             handle(listId);
           }
        });
    }
}

上記のすべては、発行したクエリの数を追跡し、それらがすべて終了したときに client.end() と handle(listId); を呼び出します。

これは面倒でエラーが発生しやすいため、非同期フローを簡単にするライブラリがいくつか存在します。私のお気に入りは非同期で、ブラウザとノードで動作します。 https://github.com/caolan/async

非同期を使用して、コードを次のように書き直します。

function addItems(listId, listItems, handle) {
    if (!listItems) {
        handle(listId);
        return;
    }
    var client = dbConnector.getClient(),
        important,
        dateArray,
        dateString,
        i, 
        prepStatement;
    client.connect();

    async.forEach(
      listItems,
      // called for each listItems
      function(listItem, callback){
        console.log(listItem);
        dateArray = listItem.itemdate.split('-');
        dateString = dateArray[1] + '-' + dateArray[0] + '-' + dateArray[2];
        if (listItem.important) {
            important = 'true';
        } else {
            important = 'false';
        }
        prepStatement = {
            name: 'insert task',
            text: 'INSERT INTO listitem (todolist_id, name, deadline, description, important, done, created) VALUES ($1, $2, $3, $4, $5, $6, now()) RETURNING listitem_id',
            values: [ listId, listItem.itemname, dateString, listItem.itemdesc, important, listItem.done ]
        };
        var query = client.query(prepStatement);
        //console.log("Adding item " + i);
        query.on('error', function(error) {
            console.log(error);
            callback(error),
        });
        query.on('end', function(result) {
           console.log("Query ended");
           if (result) {
               console.log("Added listitem no " + result.rows[0].listitem_id);
           } 
           callback(null,result);
        });
      }, 
      // called after iterator function
      function(err) {
        if (err) return; // could use this as an err handler for all queries              
        client.end();
        handle(listId);
      }
    );
}; 

async.forEachSeries も参照してください。ただし、node-postgres クライアントはクエリを連続して実行するため、この場合は必要ないと思います。

于 2012-05-08T19:24:08.977 に答える