我们刚刚更新为续集版本1.7.0-rc1。突然之后,下面的续集代码停止了工作:
exports.invalidate = function (partnerId, importStartTime, fn) {
console.log('\r\n Import start time: ' + JSON.stringify(importStartTime));
var sql = '';
sql += 'UPDATE "Product" p SET "status" = 0 FROM "Brand" b WHERE b."id" = p."BrandId" AND b."PartnerId" = ' + partnerId + ' AND p."status" <> 0 AND \
p."validatedAt" < \'' + importStartTime + '\'; ';
sql += 'UPDATE "Variant" v SET "status" = 0 FROM "Product" p INNER JOIN "Brand" b ON b."id" = p."BrandId" WHERE \
p."id" = v."ProductId" AND b."PartnerId" = ' + partnerId + ' AND v."status" <> 0 AND v."validatedAt" < \'' + importStartTime + '\'; ';
sql += 'UPDATE "ProductCategory" pc SET "status" = 0 FROM "Product" p INNER JOIN "Brand" b ON b."id" = p."BrandId" WHERE \
p."id" = pc."ProductId" AND b."PartnerId" = ' + partnerId + ' AND pc."status" <> 0 AND pc."validatedAt" < \'' + importStartTime + '\'; ';
sql += 'UPDATE "VariantImg" vi SET "status" = 0 FROM "Variant" v INNER JOIN "Product" p ON p."id" = v."ProductId" INNER JOIN "Brand" b ON b."id" = p."BrandId" WHERE \
v."id" = vi."VariantId" AND b."PartnerId" = ' + partnerId + ' AND vi."status" <> 0 AND vi."validatedAt" < \'' + importStartTime + '\'; ';
console.log('\r\n ' + sql);
sequelize.query(sql).success(function () {
console.log('\r\n Invalidation completed :)');
fn(null);
}).error(function (err) {
logExceptOnTest('\r\n Invalidation failed :(');
logExceptOnTest('\r\n Sequelize failed to set status to 0 for items that have been invalidated :(');
logExceptOnTest('\r\n err: ' + JSON.stringify(err));
fn(err);
});
}
我们正在将PostgreSql v9.3用于我们的数据存储区,并且似乎没有执行Update(sql)。如果我直接在PostgreSql中执行相同的sql,一切都按预期工作。有趣的是,如果我启用sequelize日志记录,我可以看到正在记录的更新状态。
更新:2014年1月23日
我决定将Update SQL移动到PosgreSql函数。奇怪的是,结果是一样的。如果我在PosgreSql中调用该函数,一切正常。如果我通过sequelize.query方法调用Sequelize中的函数,则会出现同样的问题。
以下是该函数的代码:
CREATE OR REPLACE FUNCTION invalidate(partnerId INTEGER, importStartTime TIMESTAMP)
RETURNS TABLE (
validatedAt TIMESTAMP,
importStartTime2 TIMESTAMP
)
AS
$$
BEGIN
UPDATE "Product" p SET "status" = 0 FROM "Brand" b WHERE b."id" = p."BrandId" AND b."PartnerId" = $1 AND p."status" <> 0 AND
p."validatedAt"::TIMESTAMP WITHOUT TIME ZONE < $2;
UPDATE "Variant" v SET "status" = 0 FROM "Product" p INNER JOIN "Brand" b ON b."id" = p."BrandId" WHERE
p."id" = v."ProductId" AND b."PartnerId" = $1 AND v."status" <> 0 AND
v."validatedAt"::TIMESTAMP WITHOUT TIME ZONE < $2;
UPDATE "ProductCategory" pc SET "status" = 0 FROM "Product" p INNER JOIN "Brand" b ON b."id" = p."BrandId" WHERE
p."id" = pc."ProductId" AND b."PartnerId" = $1 AND pc."status" <> 0 AND
pc."validatedAt"::TIMESTAMP WITHOUT TIME ZONE < $2;
UPDATE "VariantImg" vi SET "status" = 0 FROM "Variant" v INNER JOIN "Product" p ON p."id" = v."ProductId" INNER JOIN "Brand" b ON b."id" = p."BrandId" WHERE
v."id" = vi."VariantId" AND b."PartnerId" = $1 AND vi."status" <> 0 AND
vi."validatedAt"::TIMESTAMP WITHOUT TIME ZONE < $2;
RETURN QUERY select pc."validatedAt"::TIMESTAMP WITHOUT TIME ZONE as "validatedAt", $2 as "importStartTime"
from "ProductCategory" pc
inner join "Product" p on pc."ProductId" = p."id"
inner join "Brand" b on b."id" = p."BrandId"
where pc."id" = 34;
END
$$
LANGUAGE plpgsql;
如果我在PosgreSql中调用这样的函数,一切都很好:
SELECT invalidate(31, '2014-01-22 22:27:53');
如果我使用Sequelize从node.js调用这样的函数,它就不起作用:
var sql = 'SELECT invalidate(' + partnerId + ', \'' + importStartTime + '\');';
console.log('\r\n ' + sql);
sequelize.query(sql).success(function (data) {
//console.log('\r\n Invalidation completed :)');
console.log('\r\n data: ' + JSON.stringify(data));
fn(null);
}).error(function (err) {
logExceptOnTest('\r\n Invalidation failed :(');
logExceptOnTest('\r\n Sequelize failed to set status to 0 for items that have been invalidated :(');
logExceptOnTest('\r\n err: ' + JSON.stringify(err));
fn(err);
});
我已将问题缩小到sql的这一部分:
p."validatedAt"::TIMESTAMP WITHOUT TIME ZONE < $2
我认为问题在于PostgreSql和Sequelize如何存储和传递日期。 Somthing随Sequelize 1.7.0-rc1而改变,即将日期转换为与validgreAql时间戳列中PosgreSql读取的格式不匹配的格式。 通过尝试将日期发送到正确的UTC格式,我玩了一会儿。无论有没有时区我都试过,没有任何成功。我甚至在函数末尾添加了一个select来返回存储在validatedAt列中的日期以及我传递给函数的日期(importStartTime)。当在代码中(通过console.log)和在表中(直接在PostgreSql中选择)中查看它们时,两个日期显然是相同的,但是当函数调用返回它的select语句的结果时,日期不在相同的格式。所以,我相信更新版本的日期比较部分也会看到不同格式的日期,从而使得查询看起来不起作用,即使实际上是。
我更新了这篇文章的标题以反映新发现。