插入后 Knex 解析空集
Posted
技术标签:
【中文标题】插入后 Knex 解析空集【英文标题】:Knex resolving empty set after insert 【发布时间】:2017-01-15 10:24:58 【问题描述】:我正在尝试使用 Postgresql 和 Knex 在 Node 中设置一个基本的数据库连接,但我无法让看似简单的插入工作。我将大部分代码基于 Knex github repo 中的示例代码。
问题似乎是我的第一个插入(我在其中添加管理员用户)正在解析一组空行(不太确定,因为文档不包含任何关于行或行集的信息)找到)。
这是我的代码:
const knex = require("knex")(
client: "postgres",
connection:
host : "127.0.0.1",
user : "postgres",
password : "my password goes here",
database : "issue-tracker",
charset : "utf8"
);
knex.schema
.dropTableIfExists("tickets")
.dropTableIfExists("users")
.createTable("users", createUserTable)
.createTable("tickets", createTicketTable)
.then(() => addTestData())
.then(() => console.log("Done"))
.catch((e) => console.log(e));
function createUserTable(table)
table.increments("id");
table.string("username").index().unique();
table.string("password");
table.timestamps();
function createTicketTable(table)
table.increments("id");
table.timestamps();
table.integer("creator_id").unsigned().references("users.id");
table.string("text");
function addTestData()
return Promise.resolve()
.then(() =>
knex.insert(username: "admin", password: "password")
.into("users")
)
.then((rows) =>
// rows is empty?
knex.insert(creator_id: rows[0], text: "this is a test")
.into("tickets")
)
.then(() =>
knex("users").join("tickets", "users.id", "tickets.creator_id")
.select("users.id as creator_id", "users.username as creator_name", "tickets.text as text")
)
.then(console.log.bind(console));
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:Promise 处理程序必须返回一些东西。它就像一条流水线一样工作——每个工作站都必须将其工作成果放回生产线上。
knex 中的插入操作不会返回行,除非您明确告诉它们返回。 Knex 对此有.returning()
(docs)。
链中的最后一个处理程序 (console.log.bind(console)
) 不返回任何内容,因此链的最终结果是未定义的。
您不需要以Promise.resolve()
启动承诺链。您可以使用任何返回承诺的函数来启动它 - 在这里直接使用 knex()
是明智的。
所以,稍微重新安排一下,我们最终得到了这个:
function addTestData()
return knex("users")
.returning("user_id")
.insert(username: "admin", password: "password")
.then((rows) =>
return knex("tickets")
.returning("ticket_id")
.insert(creator_id: rows[0], text: "this is a test");
)
.then((rows) =>
return knex("users")
.join("tickets", "users.id", "tickets.creator_id")
.select("users.id as creator_id", "users.username as creator_name", "tickets.text as text");
)
.then((rows) =>
console.log.bind(console);
return rows;
);
这等同于这个,return
是隐含的,因此不太明显:
function addTestData()
return knex("users")
.returning("user_id")
.insert(username: "admin", password: "password")
.then((rows) => knex("tickets")
.returning("ticket_id")
.insert(creator_id: rows[0], text: "this is a test");
)
.then((rows) => knex("users")
.join("tickets", "users.id", "tickets.creator_id")
.select("users.id as creator_id", "users.username as creator_name", "tickets.text as text");
)
.then((rows) =>
console.log.bind(console);
return rows;
);
【讨论】:
这不是问题。我不想解决任何价值。我只是想插入一个用户,解析它的 id,然后插入一张票(它的 creator_id 设置为插入的用户的 id)。addTestData
无法解决任何我关心的问题。问题是rows
在第一次插入后为空。
啊。 Insert 语句通常不返回任何行。有关获取插入值的方法,请参阅github.com/tgriesser/knex/issues/732。
谢谢!问题是我没有使用returning
方法。它现在工作。如果您想修改答案,我会接受。
我一回家就编辑它。我没有准备好在手机上做这件事的痛苦。 :)以上是关于插入后 Knex 解析空集的主要内容,如果未能解决你的问题,请参考以下文章