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
_
create_hypertable で説明されているように、prices
列が_time_column_name
_であるテーブルstart
のハイパーテーブルを作成します。_chunk_time_interval
_は1日。つまり、1つのチャンクには1日のデータが必要です
例:
1つのチャンクには、start
値が_2020-04-19 00:00:00+02
_であり、end
値が_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価格ADD PRIMARY KEY(id、start)](このエラーの背景: http://sqlalche.me/e/f405 )
私のデータは次のようになります
誰かが私がしている間違いを指摘してもらえますか?
ありがとう
TimescaleDBでは、一意の主キーに時間ディメンション列を含める必要があります。一方、時間ディメンションとして定義できる列は1つだけです。制限については create_hypertable doc で読むことができます。
Flask SQL Alchemyには主キーが必要なので、時間ディメンション列に複合主キーを定義できます。これはstart
であり、id
です。 。 this doc に基づくと思います:
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
にデフォルトのインデックスを作成することに注意してください。アプリケーションクエリによっては、このインデックスが不要で、主キーで十分な場合があります。そのような場合、ハイパーテーブルを作成するための呼び出し中にオプションcreate_default_indexes
をstart
に設定するか、後でDROP INDEX
ステートメントを実行することにより、false
のインデックスを削除できます。 ベストプラクティスセクション には詳細情報が含まれています。