Jas*_*n C 13 javascript node.js bookshelf.js
我确定我错过了一些东西,但我发现Bookshelf API对我来说是无情的混淆.这是我想要做的:
Radio了一个应用程序分配的字符串主键serial,并且为了这个例子,有两个名为example1和的字段example2.我idAttribute: 'serial'在模型定义中指定了自定义ID .特别是在这个例子中:
example1和example2.example1,并留下example2不变.所以我在Bookshelf模型中有这样的东西,作为类(即"静态")方法("info"有字段"serial","example1"和"example2"):
insertOrUpdate: function (info) {
return new Radio({'serial':info.serial}).fetch().then(function (model) {
if (model) {
model.set('example1', info.example1);
return model.save({}, {
method: 'update',
patch: true
})
} else {
return new Radio({
serial: info.serial,
example1: info.example1,
example2: info.example2
}).save({}, {
method: 'insert'
})
}
}).then(function (model) {
console.log("SUCCESS");
}).catch(function (err) {
console.log("ERROR", err);
});
}
Run Code Online (Sandbox Code Playgroud)
示例电话:
Radio.insertOrUpdate({
serial: ...,
example1: ...,
example2: ...
})
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,虽然"插入"案例有效,但"更新"案例失败了:
ERROR { Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'where `serial` = '123223'' at line 1
Run Code Online (Sandbox Code Playgroud)
在打开Knex调试时很明显,生成的查询缺少set子句:
update `radios` set where `serial` = ?
Run Code Online (Sandbox Code Playgroud)
现在,我专注于书架文档的fetch和save,如果我在错误的方向我率领我不知道.
我知道我使用的API错了,但我无法理解.我注意到/必须做的一些奇怪的事情才能让它进入半工作状态:
我不明白第一个参数save.这将是有意义的我,如果保存是一个静态的方法Model,但事实并非如此.它是一个实例方法,您已经可以将属性传递给Model构造函数(例如,new X(a:1).save({a:2})意味着什么......?),并且您已经set可以在保存之前设置属性.所以我无法理解这一点.我必须{}作为占位符传递给我指定选项.
有这个forge东西,但我不确定它的目的是什么,因为你已经可以将属性传递给Model构造函数(除非作者发现一些好处X.forge({a:1})与new X({a:1})...?).
我发现由于明显的Bookshelf怪癖,我必须明确指定要保存的方法:Bookshelf基于它的方法选择isNew(),但isNew()总是true在你将id传递给模型构造函数时,你必须在应用程序分配中执行ID案例.因此,对于应用程序分配的ID,Bookshelf将始终执行"插入",因为它始终认为模型"是新的".所以你必须强制该方法"更新"...这只会增加我的Bookshelf混淆.
无论如何,我该如何正确地做到这一点?如何使此插入和更新工作?
更重要的是,这在哪里记录?本着善意,我认为它在某处清楚地记录下来,我现在看不到树木的森林,所以我真的很欣赏文档中的一些方向,而不是直接回答,因为我确实需要弄清楚这一点.我花了很多时间在Bookshelf而不是实际的开发上,以至于我几乎希望我从一开始就坚持直接进行SQL查询.
这是一个有趣的,我花了一些时间来了解发生了什么.
正如您似乎已经发现的那样,关于该选项的save()方法文档说明了patch它
仅保存参数中提供的属性以进行保存.
所以你只需要将代码更改为
if (model) {
model.set('example1', info.example1);
return model.save();
}
Run Code Online (Sandbox Code Playgroud)
并set保存属性.
但 但 但 但
所有属性都会进入update声明,甚至是id!
这是ORM的常见行为,其基本原理是,如果我们从一个事务中获取数据并从另一个事务中保存(坏的,不好的做法!),那么其他客户端可能已经更改了数据.因此,仅保存部分属性可能会导致状态不一致.
但该patch属性的存在违反了这一概念.所以Bookshelf可以通过以下方式改进:
patch选项.(我更喜欢那个)patch期权的弃用.patch语义与更改的属性相关,而不仅仅是提供的属性save().但不幸的是,这种变化可能会破坏一些用例.