在1.7.0-rc1升级后,sequelize.query方法格式化日期不同

时间:2014-01-22 02:20:57

标签: node.js postgresql sequelize.js

我们刚刚更新为续集版本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语句的结果时,日期不在相同的格式。所以,我相信更新版本的日期比较部分也会看到不同格式的日期,从而使得查询看起来不起作用,即使实际上是。

我更新了这篇文章的标题以反映新发现。

0 个答案:

没有答案