Postgresql

由於唯一索引錯誤,無法將表轉換為超表

  • May 14, 2020

我正在使用 Flask SQL Alchemy 創建一個表,如下所示:

class Price(db.Model):
   __tablename__ = "prices"
   id = db.Column(db.Integer, primary_key=True)
   country_code = db.Column(db.String(2), nullable=False)
   value = db.Column(db.Float(precision=2), nullable=False)
   start = db.Column(db.DateTime(timezone=True), nullable=False)
   end = db.Column(db.DateTime(timezone=True), nullable=False)
   price_type = db.Column(db.String(32), nullable=False)

然後我想通過執行以下操作創建表並將其轉換為超表:

def register_timescale():
   result = db.session.execute(
       "select exists(select * from timescaledb_information.hypertable " +
       " where table_name='prices')")
   is_hypertable = [row[0] for row in result]
   if is_hypertable[0] is False:
       db.session.execute(
           "SELECT create_hypertable('prices', 'start', chunk_time_interval=>INTERVAL '1 day')")
       db.session.commit()


def create_app(app_config):
   app = Flask(__name__)

   app.config.from_object(app_config)

   register_extensions(app)
   register_blueprints(app)
   with app.app_context():
       db.create_all()
       register_timescale()
   return app

我想創建一個表的超表pricesstarttime_column_namecreate_hypertable所述,chunk_time_interval應該是 1 天。意思是,一個chunk必須有1天的數據

例子:

一個塊必須包含startvalue2020-04-19 00:00:00+02endvalue 的數據2020-04-20 00:00:00+02(從下圖中的第 1 行到第 24 行),然後第二個塊必須包含從2020-04-20 00:00:00+02到的值2020-04-21 00:00:00+02(從下圖中的第 25 到 48 行)等等。

當我這樣做時,我收到以下錯誤:

發生異常:DatabaseError (psycopg2.DatabaseError) 無法創建沒有列“start”的唯一索引(用於分區)

$$ SQL: SELECT create_hypertable(‘prices’, ‘start’, chunk_time_interval=>INTERVAL ‘1 day’) $$(此錯誤的背景: http ://sqlalche.me/e/4xp6 )

register_timescale()然後,我嘗試按如下方式更改功能:

def register_timescale():
   result = db.session.execute(
       "select exists(select * from timescaledb_information.hypertable " +
       " where table_name='prices')")
   is_hypertable = [row[0] for row in result]
   if is_hypertable[0] is False:
       db.session.execute(
           "ALTER DATABASE mydb SET timezone TO 'Europe/Berlin'")
       db.session.execute("SELECT pg_reload_conf()")
       db.session.execute("ALTER TABLE prices ADD PRIMARY KEY (id, start)")
       db.session.execute(
           "SELECT create_hypertable('prices', (id, start), chunk_time_interval=>INTERVAL '1 day')")
       db.session.commit()

這給了我以下錯誤:

發生異常: ProgrammingError (psycopg2.errors.InvalidTableDefinition) 表“價格”的多個主鍵是不允許的

$$ SQL: ALTER TABLE prices ADD PRIMARY KEY (id, start) $$(此錯誤的背景:http ://sqlalche.me/e/f405 )

我的數據如下

在此處輸入圖像描述

有人可以指出我正在做的錯誤嗎?

謝謝

TimescaleDB 要求唯一鍵和主鍵包含時間維度列。雖然只能將一列定義為時間維度。您可以在create_hypertable doc中了解限制。

由於 Flask SQL Alchemy 需要主鍵,因此您可以在時間維度列上定義復合主鍵,start在您的情況下,並且id. 基於此文件,我相信它將是:

class Price(db.Model):
   __tablename__ = "prices"
   id = db.Column(db.Integer, primary_key=True)
   country_code = db.Column(db.String(2), nullable=False)
   value = db.Column(db.Float(precision=2), nullable=False)
   start = db.Column(db.DateTime(timezone=True), primary_key=True)
   end = db.Column(db.DateTime(timezone=True), nullable=False)
   price_type = db.Column(db.String(32), nullable=False)

然後你應該能夠create_hypertable成功執行語句。它應該只包括列start作為時間維度,即:

SELECT create_hypertable('prices', 'start', chunk_time_interval=>INTERVAL '1 day')

請注意,這create_hypertable還將在start. 根據您的應用程序查詢,您可能不需要此索引,主鍵可能就足夠了。在這種情況下,您可以通過在呼叫創建超表期間start將選項設置create_default_indexes為或在之後執行語句來刪除索引。最佳實踐部分包含更多資訊。false``DROP INDEX

引用自:https://dba.stackexchange.com/questions/267126