Postgres DATE_TRUNC正在更改时间戳

时间:2020-05-02 07:43:30

标签: python postgresql postgresql-11

我正在使用一个名为architect的python软件包,该软件包可帮助在Django模型中使用Postgres分区。而且我已经为每个月设置了分区表。但是在检查约束中,我看到截断的日期正在改变。例如

DATE_TRUNC('month','2020-09-12 15:23:00+05:45')给出2020-09-01 05:45:00+05:45

由于此,检查约束变为

CONSTRAINT "transactionservice_transaction_y2020m09_TransactionDate_check" CHECK ("TransactionDate" >= '2020-09-01 05:45:00+05:45'::timestamp with time zone AND "TransactionDate" < '2020-10-01 05:45:00+05:45'::timestamp with time zone)
)

这导致2020-9-1 02:03:33的事务位于2020-08的事务表中,这不是我想要的。

我从pgadmin尝试过此操作,输出为2020-09-01 00:00:00+05:45,这是我的唯一选择。

但是从Architect软件包执行的sql代码导致上述移位。

这是架构师代码中添加检查约束的部分。

def _get_date_definitions(self):
    """
    Returns definitions for date partition subtype.
    """
    patterns = {
        'day': '"y"YYYY"d"DDD',
        'week': '"y"IYYY"w"IW',
        'month': '"y"YYYY"m"MM',
        'year': '"y"YYYY',
    }
    try:
        pattern = patterns[self.constraint]
    except KeyError:
        raise PartitionConstraintError(
            model=self.model.__name__,
            dialect=self.dialect,
            current=self.constraint,
            allowed=patterns.keys())
    return {
        'formatters': {'pattern': pattern},
        'variables': [
            "match := DATE_TRUNC('{constraint}', NEW.{{column}});",
            "tablename := '{{parent_table}}_' || TO_CHAR(NEW.{{column}}, '{pattern}');",
            "checks := '{{column}} >= ''' || match || ''' AND {{column}} < ''' || (match + INTERVAL '1 {constraint}') || '''';"
        ]
    }

谁能向我解释是什么原因导致了转移

1 个答案:

答案 0 :(得分:0)

请注意,2020-09-01 05:45:00+05:452020-09-01 00:00:00Z在不同时区是同一时间点。一种在+05:45中,另一种在UTC中。您的应用程序可能会将2020-09-01 00:00:00解释为UTC,然后将其更改为应用程序的时区。

如果列是没有时区的timestamp,则date_trunc将产生没有时区的时间戳。我的时区是-0700。

select date_trunc('month', timestamp '2020-09-12 15:23:00+05:45')
2020-09-01 00:00:00

select date_trunc('month', timestamptz '2020-09-12 15:23:00+05:45')
2020-09-01 00:00:00-07

2020-09-01 00:00:00是一个模糊的时间点。您的应用程序可能会将其解释为UTC或应用程序所在的时区+05:45。似乎是将其解释为UTC,然后将其转换为应用程序的时间。在UTC中,2020-09-01 00:00:002020-09-01 05:45:00+05:45

Django documentation on time zones似乎证实了这一点。

启用时区支持后,Django将日期时间信息存储在数据库的UTC中,在内部使用可识别时区的日期时间对象,并将其转换为模板和表格形式的最终用户时区。

我不熟悉Django,无法确切说明如何解决此问题。在Troubleshooting部分中,“ 3。now.date()是昨天!(或明天)”说明了将日期时间转换为可能相关的日期的陷阱。

相关问题