如何从时间戳列中仅检索年份?

时间:2015-11-26 21:55:01

标签: python postgresql sqlalchemy flask-sqlalchemy

我有以下在Postgres 9.3上正确运行的查询:

select distinct date_part('year', date_created) 
from "Topic";

目的是仅返回由此创建的列date_created上的不同年份:

date_created  | timestamp with time zone | not null default now()

我需要把它变成一个SQLAlchemy查询,但我写的是在date_created上选择distinct,而不是在年份上,并返回整行,而不仅仅是不同的值:

topics = Topic.query.distinct(func.date_part('YEAR', Topic.date_created)).all()

我怎样才能从表格主题中获得不同的年份?

3 个答案:

答案 0 :(得分:1)

以下是两种变体:

使用ORM:

from sqlalchemy import func, distinct

result = session.query(distinct(func.date_part('YEAR', Topic.date_created)))
for row in result:
    print(row[0])

SQL表达式:

from sqlalchemy import func, select, distinct

query = select([distinct(func.date_part('YEAR', Topic.date_created))])
for row in session.execute(query):
        print(row[0])

答案 1 :(得分:1)

除了SQL Alchemy语法之外,您的查询中还有潜在问题

您的数据类型为timestamptztimestamp with time zone),这是一个不错的选择。 然而无法可靠地判断年份仅形成timestamptz,您需要另外指定时区。如果您不这样做,会话的当前时区设置将以静默方式应用,这可能适用于您,也可能不适用。

想想新年前夕:timestamptz '2016-01-01 04:00:00+00' - 今年是什么时候?

2016年在欧洲,但2015年仍在美国 您应该使用 AT TIME ZONE 结构明确说明,以避免出现偷偷摸摸的错误:

SELECT extract(year FROM timestamptz '2016-01-01 04:00:00+00'
                         AT TIME ZONE 'America/New_York') AS year;

详细说明:

date_part() and extract() do the same in Postgresextract()是SQL标准,所以请使用它。

SQL Fiddle.

顺便说一句,你也可以:

SELECT extract(year FROM date_created) AS year
FROM   "Topic"
GROUP  BY 1;

答案 2 :(得分:0)

使用extract功能:

session.query(func.extract(Topic.date_created, 'year'))

这是一个概念代码,未经过测试。