insert = async (tbl, obj, opts = Object.create(null)) => {
  const kvs = Object.entries(obj);
  const fnameList = kvs.map(([k, v]) => `"${sqlsanitize(k)}"`).join();
  var valPosList = [];
  var valList = [];
  const schema = opts.schema || getTenantSchema();
  const conflict = opts.onConflictDoNothing ? "on conflict do nothing " : "";
  kvs.forEach(([k, v]) => {
    if (v && v.next_version_by_id) {
      valList.push(v.next_version_by_id);
      valPosList.push(
        `coalesce((select max(_version) from "${schema}"."${sqlsanitize(
          tbl
        )}" where id=$${valList.length}), 0)+1`
      );
    } else {
      valList.push(v);
      valPosList.push(`$${valList.length}`);
    }
  });
  const sql =
    valPosList.length > 0
      ? `insert into "${schema}"."${sqlsanitize(
          tbl
        )}"(${fnameList}) values(${valPosList.join()}) ${conflict}returning ${
          opts.noid ? "*" : ppPK(opts.pk_name)
        }`
      : `insert into "${schema}"."${sqlsanitize(
          tbl
        )}" DEFAULT VALUES returning ${opts.noid ? "*" : ppPK(opts.pk_name)}`;
  sql_log(sql, valList);
  const { rows } = await getMyClient(opts).query(sql, valList);
  if (opts.noid) return;
  else if (conflict && rows.length === 0) return;
  else return rows[0][opts.pk_name || "id"];
}
Insert rows into table
@param {string} tbl - table name
@param {object} obj - columns names and data
@param {object} [opts = {}] - columns attributes
@returns {Promise<string>} returns primary key column or Id column value. If primary key column is not defined then return value of Id column.