Knex迁移:交易查询已完成
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Knex迁移:交易查询已完成相关的知识,希望对你有一定的参考价值。
使用knex
我想向现有表中添加2个其他列。为了预先存在记录,我想基于计算添加一个值。以下是我的迁移文件。它在第二行失败:Cannot read property 'resolve' of undefined
。
exports.up = function (knex, Promise) {
return Promise.resolve()
.then(function(){
... cut to shorten question...
})
};
更新:我删除了Promise
,现在下面有迁移代码。这仍然会产生两个错误,可能与forEach
循环有关,并且它不会等待循环的一部分完成之后再进行下一部分(但是我不知道该怎么做) ):
未处理的拒绝MigrationLocked:迁移表已被锁定
交易查询已经完成,请使用DEBUG = knex:tx来运行以获取更多信息
const Coupon = require('../../models/coupon');
const Plan = require('../../models/plan');
exports.up = function (knex) {
return knex.schema.table('transactions', (table) => {
table.decimal('plan_price', 10, 2);
table.decimal('discount', 10, 2).defaultTo(0);
})
.then(function(return_value){
knex.select().from('transactions')
.then((transactions) => {
transactions.forEach(async function(trans){
let original_price;
let total_coupon_discount = 0;
const plan = await Plan.where({id: trans.plan_id}).fetch();
if (plan) { original_price = plan.get("price") };
if (trans.coupon_id) {
const coupon = await Coupon.where({id: trans.coupon_id}).fetch();
if (coupon) {
total_coupon_discount = coupon.get("discount_amount");
original_price = trans.amount_ex_vat + couponAmount;
}
}
const promise = await knex('transactions')
.where('id', '=', trans.id)
.update({
plan_price: original_price,
discount: total_coupon_discount
}).catch(function(error){
console.log(error)
}).then(function(){
console.log('Added data to transaction record');
})
})
})
return return_value;
})
};
exports.down = function (knex) {
return knex.schema.table('transactions', (table) => {
table.dropColumn('plan_price');
table.dropColumn('discount');
});
};
Update2: @Rich Churcher的答案中建议的迁移语法使迁移得以完成。但是有关MigrationLock的错误消息仍然存在。 Here讨论了类似的问题。建议从migration_table
中删除锁,但是即使完全清空该表也对我没有影响。
所以我在DEBUG=knex:*
中添加了variables.env
,因为该网站也建议这样做。然后,当我对最新迁移进行回滚时,将获得以下输出。任何想法可能导致错误的原因以及如何解决此问题?
Using environment: development
knex:client acquired connection from pool: __knexUid1 +0ms
knex:query select * from information_schema.tables where table_name = ? and table_schema = database() undefined +0ms
knex:bindings [ 'migrations' ] undefined +0ms
knex:client releasing connection to pool: __knexUid1 +18ms
knex:client acquired connection from pool: __knexUid1 +1ms
knex:query select * from information_schema.tables where table_name = ? and table_schema = database() undefined +17ms
knex:bindings [ 'migrations_lock' ] undefined +17ms
knex:client releasing connection to pool: __knexUid1 +4ms
knex:client acquired connection from pool: __knexUid1 +10ms
knex:query select * from `migrations_lock` undefined +16ms
knex:bindings [] undefined +17ms
knex:client releasing connection to pool: __knexUid1 +5ms
knex:client acquired connection from pool: __knexUid1 +2ms
knex:query select `name` from `migrations` order by `id` asc undefined +13ms
knex:bindings [] undefined +14ms
knex:client releasing connection to pool: __knexUid1 +13ms
knex:client acquired connection from pool: __knexUid1 +26ms
knex:query select * from `migrations` where `batch` = (select max(`batch`) from `migrations`) order by `id` desc undefined +33ms
knex:bindings [] undefined +32ms
knex:client releasing connection to pool: __knexUid1 +7ms
knex:tx trx2: Starting top level transaction +0ms
knex:client acquired connection from pool: __knexUid1 +10ms
knex:query BEGIN; trx2 +34ms
knex:bindings undefined trx2 +35ms
knex:query update `migrations_lock` set `is_locked` = ? where `is_locked` = ? trx2 +7ms
knex:bindings [ 1, 0 ] trx2 +17ms
knex:query COMMIT; trx2 +20ms
knex:bindings undefined trx2 +27ms
knex:tx trx2: releasing connection +95ms
knex:client releasing connection to pool: __knexUid1 +138ms
knex:client acquired connection from pool: __knexUid1 +409ms
knex:query select max(`batch`) as `max_batch` from `migrations` trx2 +509ms
knex:bindings [] trx2 +490ms
knex:client releasing connection to pool: __knexUid1 +28ms
knex:tx trx3: Starting top level transaction +500ms
knex:client acquired connection from pool: __knexUid1 +18ms
knex:query BEGIN; trx3 +60ms
knex:bindings undefined trx3 +64ms
knex:client acquired connection from pool: __knexUid4 +42ms
knex:query select * from information_schema.tables where table_name = ? and table_schema = database() undefined +57ms
knex:bindings [ 'migrations' ] undefined +54ms
knex:query alter table `transactions` drop `plan_price` trx3 +13ms
knex:bindings [] trx3 +17ms
knex:client releasing connection to pool: __knexUid4 +82ms
knex:client acquired connection from pool: __knexUid4 +1ms
knex:query select * from information_schema.tables where table_name = ? and table_schema = database() undefined +33ms
knex:bindings [ 'migrations_lock' ] undefined +28ms
knex:client releasing connection to pool: __knexUid4 +4ms
knex:client acquired connection from pool: __knexUid4 +34ms
knex:query select * from `migrations_lock` undefined +42ms
knex:bindings [] undefined +68ms
knex:client releasing connection to pool: __knexUid4 +33ms
knex:client acquired connection from pool: __knexUid4 +3ms
knex:query select `name` from `migrations` order by `id` asc undefined +60ms
knex:bindings [] undefined +34ms
knex:client releasing connection to pool: __knexUid4 +31ms
knex:tx trx5: Starting top level transaction +240ms
knex:client acquired connection from pool: __knexUid4 +30ms
knex:query BEGIN; trx5 +33ms
knex:bindings undefined trx5 +33ms
knex:query update `migrations_lock` set `is_locked` = ? where `is_locked` = ? trx5 +3ms
knex:bindings [ 1, 0 ] trx5 +19ms
Can't take lock to run migrations: Migration table is already locked
If you are sure migrations are not running you can release the lock manually by deleting all the rows = require(migrations lock table: migrations_lock
knex:query ROLLBACK trx5 +79ms
knex:bindings undefined trx5 +63ms
knex:tx trx5: releasing connection +110ms
knex:client releasing connection to pool: __knexUid4 +86ms
Unhandled rejection MigrationLocked: Migration table is already locked
(No stack trace)
From previous event:
at Migrator._getLock (C:Usersxxx
ode_modulesknexlibmigrateMigrator.js:328:13)
at Migrator._runBatch (C:Usersxxx
ode_modulesknexlibmigrateMigrator.js:343:12)
at knex.transaction (C:Usersxxx
ode_modulesknexlibmigrateMigrator.js:92:25)
at init.then.then (C:Usersxxx
ode_modulesknexlib ransaction.js:91:24)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
From previous event:
at Transaction._promise.Bluebird.using (C:Usersxxx
ode_modulesknexlib ransaction.js:77:12)
at runCallback (timers.js:705:18)
From previous event:
at new Transaction (C:Usersxxx
ode_modulesknexlib ransaction.js:57:30)
at new Transaction_mysql (C:Usersxxx
ode_modulesknexlibdialectsmysql ransaction.js:7:1)
at Client_MySQL.transaction (C:Usersxxx
ode_modulesknexlibdialectsmysqlindex.js:52:12)
at Function.transaction (C:Usersxxx
ode_modulesknexlibutilmake-knex.js:40:31)
at migrationListResolver.listAllAndCompleted.then.then (C:Usersxxx
ode_modulesknexlibmigrateMigrator.js:91:28)
From previous event:
at Migrator.latest (C:Usersxxx
ode_modulesknexlibmigrateMigrator.js:72:8)
at Object.<anonymous> (C:Usersxxxdbindex.js:9:14)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at Object.<anonymous> (C:Usersxxxmodelscoupon.js:1:81)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
at Module.require (internal/modules/cjs/loader.js:637:17)
at require (internal/modules/cjs/helpers.js:22:18)
at Object.<anonymous> (C:Usersxxxdbmigrations20200105152452_add_plan_price_and_discount_to_transactions.js:1:78)
at Module._compile (internal/modules/cjs/loader.js:701:30)
From previous event:
at Migrator._runBatch (C:Usersxxx
ode_modulesknexlibmigrateMigrator.js:363:10)
at migrationListResolver.listAllAndCompleted.then.then.then (C:Usersxxx
ode_modulesknexlibmigrateMigrator.js:193:23)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
From previous event:
at Promise (C:Usersxxx
ode_modulesknexlibmigrateMigrator.js:192:10)
at new Promise (<anonymous>)
at Migrator.rollback (C:Usersxxx
ode_modulesknexlibmigrateMigrator.js:167:12)
at Command.commander.command.description.option.option.action (C:UsersxxxAppDataRoaming
pm
ode_modulesknexincli.js:231:18)
at Command.listener (C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulescommanderindex.js:360:8)
at Command.emit (events.js:189:13)
at Command.parseArgs (C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulescommanderindex.js:799:12)
at Command.parse (C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulescommanderindex.js:563:21)
at Liftoff.invoke (C:UsersxxxAppDataRoaming
pm
ode_modulesknexincli.js:344:13)
at Liftoff.execute (C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulesliftoffindex.js:201:12)
at module.exports (C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulesflagged-respawnindex.js:51:3)
at Liftoff.<anonymous> (C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulesliftoffindex.js:191:5)
at C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulesliftoffindex.js:149:9
at C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulesv8flagsindex.js:138:14
at C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulesv8flagsindex.js:41:14
at C:UsersxxxAppDataRoaming
pm
ode_modulesknex
ode_modulesv8flagsindex.js:53:7
at process._tickCallback (internal/process/next_tick.js:61:11)
knex:query alter table `transactions` drop `discount` trx3 +382ms
knex:bindings [] trx3 +383ms
knex:query COMMIT; trx3 +391ms
knex:bindings undefined trx3 +391ms
knex:tx trx3: releasing connection +777ms
knex:client releasing connection to pool: __knexUid1 +803ms
knex:client acquired connection from pool: __knexUid1 +26ms
knex:query delete from `migrations` where `name` = ? trx3 +60ms
knex:bindings [ '20200105152452_add_plan_price_and_discount_to_transactions.js' ] trx3 +59ms
knex:client releasing connection to pool: __knexUid1 +17ms
knex:client acquired connection from pool: __knexUid1 +17ms
knex:query update `migrations_lock` set `is_locked` = ? trx3 +34ms
knex:bindings [ 0 ] trx3 +34ms
knex:client releasing connection to pool: __knexUid1 +18ms
[knex -V
返回:“ Knex CLI版本:0.20.2”和“ Knex本地版本:0.20.3”。
Knex不再采用第二个Promise
参数,因为它转而使用了一段时间的本机Promise。因此,Promise
在您的迁移中是undefined
,因此绝对没有.resolve
属性。
有人认为返回Promise.resolve().then
绝对是个好主意,这很奇怪。您要执行的是模式修改,然后是数据修改。看起来像这样:
return knex.schema.table("transactions", t => {
t.decimal('plan_price', 10, 2);
// etc
})
.then(() =>
knex("transactions")
.then(
// Update values here
);
)
.catch(console.error)
此外,您发现for_each
并不总是非常适合异步工作。但是,我们仍然可以通过编写更复杂的查询(加入其他表格以获取我们想要的值)或通过修改当前表格以更好地与承诺:
exports.up = knex =>
knex.schema
.table("transactions", t => {
t.decimal("plan_price", 10, 2);
t.decimal("discount", 10, 2).defaultTo(0);
})
.then(() => {
return knex("transactions").then(async transactions => {
for (let trans of transactions) {
let original_price;
let total_coupon_discount = 0;
const plan = await Plan.where({ id: trans.plan_id }).fetch();
if (plan) {
original_price = plan.get("price");
}
if (trans.coupon_id) {
const coupon = await Coupon.where({ id: trans.coupon_id }).fetch();
if (coupon) {
total_coupon_discount = coupon.get("discount_amount");
original_price = trans.amount_ex_vat + couponAmount;
}
}
await knex("transactions")
.where("id", "=", trans.id)
.update({
plan_price: original_price,
discount: total_coupon_discount
});
}
});
});
我显然不能说出其他代码的正确性(在我看来像书架吗?),因为我没有您的架构,但这是总体思路。基本上,当你想使用async
/ await
与for... of
搭配使用,可以使所有内容保持良好顺序。
[我认为值得注意的是,这种方法在大桌子上可能会比较慢,因为有三个transactions
的每行单独的阻止查询。
以上是关于Knex迁移:交易查询已完成的主要内容,如果未能解决你的问题,请参考以下文章
时光簿SKM代码库迁移到GitHub(已完成第一阶段的20%)