From 93198254f639281d782bd5fd7e53962d1d9dcc3b Mon Sep 17 00:00:00 2001 From: eclipse Date: Thu, 17 Jul 2025 09:45:23 +0200 Subject: [PATCH] improved handling of empty DB; "tables,py" now contains verbatim code from sqlacodegen, eliminating the need for code reformatting --- the_works/database.py | 23 +++++++++------ the_works/tables.py | 66 ++++++++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/the_works/database.py b/the_works/database.py index fd35f2b..fdd805c 100644 --- a/the_works/database.py +++ b/the_works/database.py @@ -5,14 +5,21 @@ db = SQLAlchemy() def init_db(app): db.init_app(app) with app.app_context(): - print(f"number of db tables is {len(db.metadata.tables)}") + # check if database is empty and if so, populate it with fresh tables + #TODO: does it make sense to try and create all tables by default? Existing tables wouldn't be overwritten but what about DB constraints ? + if not len(db.metadata.tables): + # import table classes from code that was generated via `sqlacodegen --generator tables sqlite:///the_works.sqlite > ./the_works/tables.py` in project root + import the_works.tables - # populate an empty DB with fresh tables - #TODO: maybe add tables to metadata in any case since tables won't get overwritten - if not len(db.metadata.tables): - from the_works.tables import add_tables - add_tables(db.metadata) + # filter the objects just imported for those of type sqlalchemy.Table + from sqlalchemy import Table + table_list = list(filter(lambda t: type(t) == Table, vars(the_works.tables).values())) + + # Table objects imported from sqlacodegen code are associated with a random MetaData() object, so we have to re-associate them with the DB's metadata + table_list = list(map(lambda t: t.to_metadata(db.metadata), table_list)) + + # create tables in DB ) db.metadata.create_all(db.engine) - print(f"and now number of db tables is {len(db.metadata.tables)}") - + + # generate declarative table objects by reflecting the DB db.reflect() diff --git a/the_works/tables.py b/the_works/tables.py index c2ea897..25ffcba 100644 --- a/the_works/tables.py +++ b/the_works/tables.py @@ -1,39 +1,41 @@ -# File content is based on the output of `sqlacodegen --generator tables sqlite:///path/to/the_works.sqlite` +# file created via `sqlacodegen --generator tables sqlite:///path/to/the_works.sqlite > tables.py` from sqlalchemy import Column, ForeignKey, Integer, LargeBinary, MetaData, Table, Text -def add_tables(metadata): - t_Genre = Table( +metadata = MetaData() + + +t_Genre = Table( 'Genre', metadata, Column('ID', Integer, primary_key=True), Column('Genre', Text, nullable=False) - ) +) - t_Herausgeber = Table( +t_Herausgeber = Table( 'Herausgeber', metadata, Column('ID', Integer, primary_key=True), Column('Name', Text, nullable=False) - ) +) - t_Pseudonym = Table( +t_Pseudonym = Table( 'Pseudonym', metadata, Column('ID', Integer, primary_key=True), Column('Pseudonym', Text, nullable=False) - ) +) - t_Sprache = Table( +t_Sprache = Table( 'Sprache', metadata, Column('ID', Integer, primary_key=True), Column('Sprache', Text, nullable=False) - ) +) - t_Textform = Table( +t_Textform = Table( 'Textform', metadata, Column('ID', Integer, primary_key=True), Column('Textform', Text, nullable=False) - ) +) - t_Titelbild = Table( +t_Titelbild = Table( 'Titelbild', metadata, Column('ID', Integer, primary_key=True), Column('Mimetype', Text, nullable=False), @@ -44,28 +46,28 @@ def add_tables(metadata): Column('Bild', LargeBinary, nullable=False), Column('Thumbnail', LargeBinary, nullable=False), Column('sha256', Text, nullable=False, unique=True) - ) +) - t_Verlag = Table( +t_Verlag = Table( 'Verlag', metadata, Column('ID', Integer, primary_key=True), Column('Verlag', Text, nullable=False) - ) +) - t_Werksform = Table( +t_Werksform = Table( 'Werksform', metadata, Column('ID', Integer, primary_key=True), Column('Werksform', Text, nullable=False) - ) +) - t_Reihe = Table( +t_Reihe = Table( 'Reihe', metadata, Column('ID', Integer, primary_key=True), Column('Titel', Text, nullable=False), Column('Verlag', ForeignKey('Verlag.ID')) - ) +) - t_Text = Table( +t_Text = Table( 'Text', metadata, Column('ID', Integer, primary_key=True), Column('Titel', Text, nullable=False), @@ -73,9 +75,9 @@ def add_tables(metadata): Column('Reihe', ForeignKey('Reihe.ID')), Column('Textform', ForeignKey('Textform.ID')), Column('Sprache', ForeignKey('Sprache.ID')) - ) +) - t_Werk = Table( +t_Werk = Table( 'Werk', metadata, Column('ID', Integer, primary_key=True), Column('Titel', Text, nullable=False), @@ -92,15 +94,15 @@ def add_tables(metadata): Column('Titelbild', ForeignKey('Titelbild.ID')), Column('Klappentext', Text), Column('Anmerkungen', Text) - ) +) - t_Text_Genre = Table( +t_Text_Genre = Table( 'Text_Genre', metadata, Column('Text', ForeignKey('Text.ID'), primary_key=True), Column('Genre', ForeignKey('Genre.ID'), primary_key=True) - ) +) - t_Veroeffentlichung = Table( +t_Veroeffentlichung = Table( 'Veroeffentlichung', metadata, Column('ID', Integer, primary_key=True), Column('Text', ForeignKey('Text.ID'), nullable=False), @@ -108,16 +110,16 @@ def add_tables(metadata): Column('AltTitel', Text), Column('AltUntertitel', Text), Column('Pseudonym', ForeignKey('Pseudonym.ID'), nullable=False) - ) +) - t_Werk_Genre = Table( +t_Werk_Genre = Table( 'Werk_Genre', metadata, Column('Werk', ForeignKey('Werk.ID'), primary_key=True), Column('Genre', ForeignKey('Genre.ID'), primary_key=True) - ) +) - t_Werk_Herausgeber = Table( +t_Werk_Herausgeber = Table( 'Werk_Herausgeber', metadata, Column('Herausgeber', ForeignKey('Herausgeber.ID'), primary_key=True), Column('Werk', ForeignKey('Werk.ID'), primary_key=True) - ) +)