postgresql 打开连接并执行多个命令

postgresql open connection and execute more then one command

我想使用dart 的postgresql 驱动程序进行以下两个插入操作。 下面的代码有效!

INSERT INTO posts(
            title, description, posted_at, last_edited, "user", 
            editor, up_votes, down_votes, flag, links_to)
    VALUES ('test title', 'test description', now(), now(), 'dartUser', 'dartUser', 
            0, 0, 'healthy', 'http://google.com');


INSERT INTO atatched_tags(
            post_id, tag)
    VALUES (currval('posts_post_id_seq'), 'testTag');

仅当为 dart 方法提供可选参数时,才应执行第二次插入。 我现在拥有的代码如下所示。

  addPost(Map post_values, [Map tag_values]){
    Connection conn;
    connect(uri)
    .then((_conn){
      conn = _conn;
    })
    .then((_){
      conn.execute('''insert into posts(title, description, posted_at, last_edited, "user", editor, up_votes, down_votes, flag, links_to)
                                  values(@title, @description, now(), now(), @user, @editor, @upVotes, @downVotes, @flag, @links_to)''', post_values)
      .catchError((err){
        print('Execute error in addPost: $err');
    })
    .then((_){
      if(tag_values != null){
        _addTagToPost(conn, tag_values);
      }
    })
    .whenComplete(() => conn.close());
    })
    .catchError((err) => print('Error in addPost: $err'));
  }

  _addTagToPost(Connection conn, Map values) {
    print('trying to add tag to attached tags');
    conn.execute("insert into atatched_tags values(currval('posts_post_id_seq'), @tag)", values)
    .catchError((err){
      print('Execute error in addTagToPost: $err');
    });
  }

我运行方法如下

dbUtil.addPost({'title': 'Sample title', 
    'description': 'This is a description for a sample post', 
    'user': 'dartUser', 'editor': 'dartUser', 'upVotes': 0,
    'downVotes': 0, 'flag': 'healthy', 'links_to': 
    'http://google.com'}, {'tag':'testTag'});

dbUtil 是上面两个方法所在的 class 的实例。

代码没有抛出任何错误。但即使它写入控制台 trying to add tag to attached tags,第二个插入操作也不会执行(没有行添加到 table)。第一个按预期工作。

非常感谢任何帮助。

编辑:如果有人想在 _addTagToPost 函数中添加多个标签,那么这段代码可能会有帮助。 Edit2:下面的代码 不正确 我保留它,但请检查接受的答案中的评论。

  Future _addTagToPost(Connection conn, List<Map> values) {
    var completer = new Completer();
    values.forEach((value){
      conn.execute("insert into attached_tags values(currval('posts_post_id_seq'), @tag)", value)
          .catchError((err){
            print('Execute error in addTagToPost: $err');
          });
    });
    return completer.future;
  }

您需要在此处添加一个return

return _addTagToPost(conn, tag_values);

Future _addTagToPost(Connection conn, Map values) {
  print('trying to add tag to attached tags');
  return conn.execute(
      "insert into atatched_tags values(currval('posts_post_id_seq'),
      @tag)", values)
  .catchError((err){
    print('Execute error in addTagToPost: $err');
  });
}

保持异步操作连接。否则连接会在 _addTagToPost() 完成之前关闭,这会导致无法完成此 SQL 语句。

更新问题中的编辑。这也可以像

Future _addTagToPost(Connection conn, List<Map> values) {
  return Future.wait(values.map((value){
    return conn.execute("insert into attached_tags values(currval('posts_post_id_seq'), @tag)", value)
        .catchError((err){
          print('Execute error in addTagToPost: $err');
        });
  }));
}

Future _addTagToPost(Connection conn, List<Map> values) =>
    Future.wait(values.map((value) => conn
        .execute(
            "insert into attached_tags values(currval('posts_post_id_seq'), @tag)",
            value)
        .catchError((err) => print('Execute error in addTagToPost: $err'))));