From c770470b58608134db9a14aed586330e5c540c3d Mon Sep 17 00:00:00 2001 From: Blake Blackshear Date: Thu, 24 Dec 2020 07:47:27 -0600 Subject: [PATCH] add database migrations --- docker/Dockerfile.base | 1 + frigate/app.py | 7 ++++- frigate/models.py | 2 ++ migrations/001_create_events_table.py | 41 +++++++++++++++++++++++++++ migrations/002_add_clip_snapshot.py | 41 +++++++++++++++++++++++++++ 5 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 migrations/001_create_events_table.py create mode 100644 migrations/002_add_clip_snapshot.py diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index 9838315f2..af3bcaa9d 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -31,6 +31,7 @@ RUN apt-get -qq update \ RUN pip3 install \ peewee \ + peewee_migrate \ zeroconf \ voluptuous diff --git a/frigate/app.py b/frigate/app.py index 792358dd5..f32b1779a 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -8,6 +8,7 @@ import sys import signal import yaml +from peewee_migrate import Router from playhouse.sqlite_ext import SqliteExtDatabase from frigate.config import FrigateConfig @@ -112,9 +113,13 @@ class FrigateApp(): def init_database(self): self.db = SqliteExtDatabase(self.config.database.path) + + # Run migrations + router = Router(self.db) + router.run() + models = [Event] self.db.bind(models) - self.db.create_tables(models, safe=True) def init_stats(self): self.stats_tracking = stats_init(self.camera_metrics, self.detectors) diff --git a/frigate/models.py b/frigate/models.py index cef807538..c8bbd9ca2 100644 --- a/frigate/models.py +++ b/frigate/models.py @@ -12,3 +12,5 @@ class Event(Model): false_positive = BooleanField() zones = JSONField() thumbnail = TextField() + has_clip = BooleanField(default=True) + has_snapshot = BooleanField(default=True) diff --git a/migrations/001_create_events_table.py b/migrations/001_create_events_table.py new file mode 100644 index 000000000..fcc845cbc --- /dev/null +++ b/migrations/001_create_events_table.py @@ -0,0 +1,41 @@ +"""Peewee migrations -- 001_create_events_table.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['model_name'] # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.python(func, *args, **kwargs) # Run python code + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.drop_index(model, *col_names) + > migrator.add_not_null(model, *field_names) + > migrator.drop_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + +""" + +import datetime as dt +import peewee as pw +from decimal import ROUND_HALF_EVEN + +try: + import playhouse.postgres_ext as pw_pext +except ImportError: + pass + +SQL = pw.SQL + +def migrate(migrator, database, fake=False, **kwargs): + migrator.sql('CREATE TABLE IF NOT EXISTS "event" ("id" VARCHAR(30) NOT NULL PRIMARY KEY, "label" VARCHAR(20) NOT NULL, "camera" VARCHAR(20) NOT NULL, "start_time" DATETIME NOT NULL, "end_time" DATETIME NOT NULL, "top_score" REAL NOT NULL, "false_positive" INTEGER NOT NULL, "zones" JSON NOT NULL, "thumbnail" TEXT NOT NULL)') + migrator.sql('CREATE INDEX IF NOT EXISTS "event_label" ON "event" ("label")') + migrator.sql('CREATE INDEX IF NOT EXISTS "event_camera" ON "event" ("camera")') + +def rollback(migrator, database, fake=False, **kwargs): + pass diff --git a/migrations/002_add_clip_snapshot.py b/migrations/002_add_clip_snapshot.py new file mode 100644 index 000000000..4f425f98e --- /dev/null +++ b/migrations/002_add_clip_snapshot.py @@ -0,0 +1,41 @@ +"""Peewee migrations -- 002_add_clip_snapshot.py. + +Some examples (model - class or model name):: + + > Model = migrator.orm['model_name'] # Return model in current state by name + + > migrator.sql(sql) # Run custom SQL + > migrator.python(func, *args, **kwargs) # Run python code + > migrator.create_model(Model) # Create a model (could be used as decorator) + > migrator.remove_model(model, cascade=True) # Remove a model + > migrator.add_fields(model, **fields) # Add fields to a model + > migrator.change_fields(model, **fields) # Change fields + > migrator.remove_fields(model, *field_names, cascade=True) + > migrator.rename_field(model, old_field_name, new_field_name) + > migrator.rename_table(model, new_table_name) + > migrator.add_index(model, *col_names, unique=False) + > migrator.drop_index(model, *col_names) + > migrator.add_not_null(model, *field_names) + > migrator.drop_not_null(model, *field_names) + > migrator.add_default(model, field_name, default) + +""" + +import datetime as dt +import peewee as pw +from decimal import ROUND_HALF_EVEN +from frigate.models import Event + +try: + import playhouse.postgres_ext as pw_pext +except ImportError: + pass + +SQL = pw.SQL + + +def migrate(migrator, database, fake=False, **kwargs): + migrator.add_fields(Event, has_clip=pw.BooleanField(default=True), has_snapshot=pw.BooleanField(default=True)) + +def rollback(migrator, database, fake=False, **kwargs): + migrator.remove_fields(Event, ['has_clip', 'has_snapshot'])