#32 Add a system for applying migrations

Zusammengeführt
getty hat 2 Commits von getty/trevor/add-migrations nach getty/master vor 4 Jahren zusammengeführt
6 geänderte Dateien mit 80 neuen und 0 gelöschten Zeilen
  1. 18 0
      lc/migration.py
  2. 14 0
      lc/model.py
  3. 2 0
      migrations/__init__.py
  4. 8 0
      migrations/m_0001_add_meta_table.py
  5. 26 0
      scripts/migrate.py
  6. 12 0
      tasks.py

+ 18 - 0
lc/migration.py

@@ -0,0 +1,18 @@
+import re
+
+registered = []
+
+module_name_regex = re.compile('^.*m_([0-9]+)_([a-z_]+)')
+
+class Migration:
+    def __init__(self, version, name, method):
+        self.version = int(version)
+        self.name = name
+        self.method = method
+
+    def run(self, db):
+        self.method(db)
+
+def migration(method):
+    version, name = module_name_regex.match(method.__module__).groups()
+    registered.append(Migration(version, name, method))

+ 14 - 0
lc/model.py

@@ -26,6 +26,19 @@ class Model(peewee.Model):
             yield
 
 
+class Meta(Model):
+
+    version = peewee.IntegerField(default=0)
+
+    @staticmethod
+    def fetch():
+        try:
+            return Meta.get(id=0)
+        except:
+            meta = Meta.create(id=0)
+            return meta
+
+
 class User(Model):
     """
     A user! you know tf this is about
@@ -385,6 +398,7 @@ class UserInvite(Model):
 
 
 MODELS = [
+    Meta,
     User,
     Link,
     Tag,

+ 2 - 0
migrations/__init__.py

@@ -0,0 +1,2 @@
+
+from . import m_0001_add_meta_table

+ 8 - 0
migrations/m_0001_add_meta_table.py

@@ -0,0 +1,8 @@
+
+from lc.migration import migration
+
+# This migration just ensures that the meta table is updated to version 1
+
+@migration
+def run(m):
+    pass

+ 26 - 0
scripts/migrate.py

@@ -0,0 +1,26 @@
+import sys
+import playhouse.migrate
+
+import lc.config as c
+import lc.model as m
+import lc.migration
+
+c.app.init_db()
+m.create_tables()
+
+meta = m.Meta.fetch()
+print(f"Current schema version is: {meta.version}")
+
+import migrations
+
+runnable = filter(lambda m: m.version > meta.version, lc.migration.registered)
+
+for migration in sorted(runnable, key=lambda m: m.version):
+    print(f"{migration.version} - {migration.name}")
+    try:
+        migration.run(playhouse.migrate.SqliteMigrator(c.app.db))
+    except:
+        sys.exit(1)
+
+    meta.version = migration.version
+    meta.save()

+ 12 - 0
tasks.py

@@ -21,6 +21,18 @@ def run(c, port=8080, host="127.0.0.1"):
         },
     )
 
+@task
+def migrate(c, port=8080, host="127.0.0.1"):
+    """Run migrations to update the database schema"""
+    c.run(
+        f"PYTHONPATH=$(pwd) poetry run python3 scripts/migrate.py",
+        env={
+            "FLASK_APP": "lament-configuration.py",
+            "LC_APP_PATH": f"http://{host}:{port}",
+            "LC_DB_PATH": f"test.db",
+            "LC_SECRET_KEY": f"TESTING_KEY",
+        },
+    )
 
 @task
 def install(c):