Postgresql 错误:无法创建没有列“0”的唯一索引;日期“时间”;(用于分区)

Postgresql 错误:无法创建没有列“0”的唯一索引;日期“时间”;(用于分区),postgresql,timescaledb,Postgresql,Timescaledb,我刚开始使用postgresql。我有一个名为storage\u db的数据库,其中包含一个名为day\u ahead\u prices的表 在安装timescaledb之后,我开始将我的storage\u db迁移到timescaledb中 当我这样做时(包括索引): 它给了我以下错误: ERROR: cannot create a unique index without the column "date_time" (used in partitioning) 但当我这样做时(不包括索

我刚开始使用postgresql。我有一个名为
storage\u db
的数据库,其中包含一个名为
day\u ahead\u prices
的表

在安装timescaledb之后,我开始将我的
storage\u db
迁移到timescaledb中

当我这样做时(包括索引):

它给了我以下错误:

ERROR:  cannot create a unique index without the column "date_time" (used in partitioning)
但当我这样做时(不包括索引):

这是成功的。接下来,我做了

select create_hypertable('tsdb_day_ahead_prices', 'date_time');
它给了我以下输出:

         create_hypertable          
------------------------------------
 (3,public,tsdb_day_ahead_prices,t)
(1 row)
我对这一点有点陌生,所以任何人都可以向我解释一下他们之间的区别,以及为什么在第一个案例中我会出错

附言:

我的
日前价格如下所示:

 id | country_code | values  |         date_time          
----+--------------+---------+----------------------------
  1 | LU           | 100.503 | 2020-04-11 14:04:30.461605
  2 | LU           | 100.503 | 2020-04-11 14:18:39.600574
  3 | DE           |  106.68 | 2020-04-11 15:59:10.223965
编辑1:

我使用
flask
flask\u-sqlalchemy
python
中创建了
day\u-ahead\u-prices
表,代码是:

class day_ahead_prices(db.Model):
    __tablename__ = "day_ahead_prices"
    id = db.Column(db.Integer, primary_key=True)
    country_code = db.Column(avail_cc_enum, nullable=False)
    values = db.Column(db.Float(precision=2), nullable=False)
    date_time = db.Column(db.DateTime, default=datetime.now(tz=tz), nullable=False)

    def __init__(self, country_code, values):
        self.country_code = country_code
        self.values = values

执行
创建表tsdb_day_ahead_prices(如day_ahead_prices,包括默认值,包括约束,包括索引)时
您告诉数据库使用
day\u-ahead\u-prices
作为模板创建
tsdb\u-day\u-ahead\u-prices
表(相同的列,这些列的类型相同),但您也告诉它包括您在原始表上定义的默认值、约束和索引,并为新表应用/创建相同的

然后执行timescaledb命令,使
tsdb\u day\u ahead\u prices
表 超表格。超表是一种抽象,它隐藏了物理数据的分区 桌子(). 你说得对 TimescaleDB使用
date\u time
列作为分区键,使
tsdb\u day\u ahead\u prices
成为超表格

在创建超表时,TimescaleDB施加的一个约束是分区列(在您的示例中为“date_time”)必须包含在该表的任何唯一索引(和主键)中。()

您遇到的第一个错误
就是因为没有列“date\u time”
而无法创建唯一索引。您复制了
id
列上的主键定义。因此,主要的关键是防止 该表将是一个超级表

第二次,您创建了
tsdb\u day\u ahead\u prices
表,但没有复制 索引来自原始表,因此没有定义主键(这实际上是一个唯一的索引)。因此,超表格的创建是成功的

create_hypertable函数的输出告诉您在公共模式中有一个新的hypertable,hypertable的名称以及timescaledb用于它的内部id

因此,现在您可以正常使用
tsdb\u day\u ahead\u prices
,下面的timescaledb将确保数据进入正确的分区/区块

此表的id是否需要唯一? 如果你要保存时间序列数据 然后,对于每个id,每一行实际上可能不是唯一的,但是在给定的时间可以由id唯一地标识

您可以为要标识的项目创建单独的表
项目(id主键、国家/地区代码)
并具有超表格
提前一天\u价格(时间、价值、项目id参考项目(id))

我需要这个来写一个更详细的答案。你的
day\u ahead\u prices
表中的某些列是否有唯一的索引?嘿@BlagojAtanasovski,我编辑了我的问题。
id
列是唯一的列,因此主键i有相同的错误,解决方法是删除转换为hypertable的表上的主键。单独的表还有助于减少存储。还可以查看时间尺度压缩和连续聚合
 id | country_code | values  |         date_time          
----+--------------+---------+----------------------------
  1 | LU           | 100.503 | 2020-04-11 14:04:30.461605
  2 | LU           | 100.503 | 2020-04-11 14:18:39.600574
  3 | DE           |  106.68 | 2020-04-11 15:59:10.223965
class day_ahead_prices(db.Model):
    __tablename__ = "day_ahead_prices"
    id = db.Column(db.Integer, primary_key=True)
    country_code = db.Column(avail_cc_enum, nullable=False)
    values = db.Column(db.Float(precision=2), nullable=False)
    date_time = db.Column(db.DateTime, default=datetime.now(tz=tz), nullable=False)

    def __init__(self, country_code, values):
        self.country_code = country_code
        self.values = values