From 14c1c75d81fd6fcaf375f9b8326947bca994c233 Mon Sep 17 00:00:00 2001 From: Marcus Steinbach Date: Thu, 21 Aug 2025 12:02:07 +0200 Subject: [PATCH 1/2] fix: pre commit --- definitions/orm_tables.py | 102 +++++++++++++++++++++++++++++++++ definitions/orm_views.py | 4 ++ definitions/pg_aggregates.py | 4 ++ definitions/pg_extensions.py | 4 ++ definitions/pg_functions.py | 4 ++ definitions/pg_policies.py | 4 ++ definitions/pg_publications.py | 4 ++ definitions/pg_seeds.py | 25 ++++++++ definitions/pg_triggers.py | 4 ++ src/sqlacodegen/cli.py | 5 +- 10 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 definitions/orm_tables.py create mode 100644 definitions/orm_views.py create mode 100644 definitions/pg_aggregates.py create mode 100644 definitions/pg_extensions.py create mode 100644 definitions/pg_functions.py create mode 100644 definitions/pg_policies.py create mode 100644 definitions/pg_publications.py create mode 100644 definitions/pg_seeds.py create mode 100644 definitions/pg_triggers.py diff --git a/definitions/orm_tables.py b/definitions/orm_tables.py new file mode 100644 index 0000000..9be87ab --- /dev/null +++ b/definitions/orm_tables.py @@ -0,0 +1,102 @@ +from typing import Optional + +from risclog.claimxdb.database.base import PortalObject +from sqlalchemy import ARRAY, Column, Date, DateTime, Double, FetchedValue, Index, Integer, Numeric, PrimaryKeyConstraint, String, Table, Text, Time, text +from sqlalchemy.orm import Mapped, mapped_column +import datetime + +t_eventlog = Table( + 'eventlog', PortalObject.metadata, + Column('eventid', Integer), + Column('eventtyp', String(30)), + Column('datum', Date), + Column('uhrzeit', DateTime), + Column('ukz', String(20)), + Column('fktname', String(50)), + Column('man', String(4)), + Column('request', Text), + Column('errortype', String(255)), + Column('errorvalue', Text), + Column('traceback', Text), + Column('skriptname', String(50)), + Column('details', Text), + Column('scode', Text), + Index('i_ev_tagesdatum', 'eventtyp', 'datum', postgresql_using=False) +) + +class Eventlogadmin(PortalObject): # type: ignore[misc] + __tablename__ = 'eventlogadmin' + __table_args__ = ( + PrimaryKeyConstraint('eventtyp', name='eventlogadmin_pkey'), + {'comment': 'Admin Event-Log'} + ) + + eventtyp: Mapped[str] = mapped_column(String(30), primary_key=True, comment='Eventtyp') + ignored_exceptions: Mapped[Optional[str]] = mapped_column(Text, comment='Ignored exceptions, getrennt durch CR') + +t_eventmail = Table( + 'eventmail', PortalObject.metadata, + Column('eventtyp', String(30)), + Column('skriptname', String(50)), + Column('fktname', String(50)), + Column('errortype', String(255)) +) + +t_importlog = Table( + 'importlog', PortalObject.metadata, + Column('ukz', String(20), comment='Fuhrparkimport Hochladender Benutzer'), + Column('man', String(4), comment='Fuhrparkimport angegebener Import-Mandant'), + Column('importdat', Date, comment='Fuhrparkimport Importdatum'), + Column('file', String(255), comment='Fuhrparkimport Pfad zur Quelldatei'), + Column('dl', String(30), comment='Fuhrparkimport angegebener Dienstleister - Import-Schema'), + Column('typ', String(20), comment='Fuhrparkimport Art Fahrzeuge / Fahrer'), + Column('info', Text, comment='Fuhrparkimport Fehler/Ereignisse/Hinweise'), + Column('status', String(30), comment='Fuhrparkimport status - Importiert ?'), + Column('cnt', Integer, comment='Fuhrparkimport Anzahl importierter Zeilen'), + Column('importid', Integer), + Column('zas', Text, comment='Sendungsdatenschnittstelle'), + Column('abrufdat', DateTime, comment='Datum des Sendungsdatumsabrufes'), + Column('sndnr', Text, comment='Sendungsdatum'), + Column('produkt', String(20), comment='Produkt'), + Column('zasinfo', String(30), comment='Zusatzinfo ZAS'), + Column('dtyp', String(1), comment='Aktentyp: (S)chaden, (P)rotokoll'), + Column('snddat', Date), + Column('abrufsec', Double(53), comment='Abrufdauer in sec'), + Column('fzgid', String(20)), + comment='Fehlerlog Fuhrparkimport' +) + +class Requestlog(PortalObject): # type: ignore[misc] + __tablename__ = 'requestlog' + __table_args__ = ( + PrimaryKeyConstraint('logid', name='requestlog_pkey'), + Index('i_logdatum', 'datum', 'zeit', postgresql_using=False), + Index('i_logman', 'man', postgresql_using=False), + Index('i_logukz', 'ukz', 'datum', postgresql_using=False) + ) + + logid: Mapped[int] = mapped_column(Integer, primary_key=True) + ukz: Mapped[str] = mapped_column(String(20)) + man: Mapped[str] = mapped_column(String(4)) + zopeid: Mapped[str] = mapped_column(String(50)) + datum: Mapped[datetime.date] = mapped_column(Date) + zeit: Mapped[datetime.time] = mapped_column(Time) + url: Mapped[Optional[str]] = mapped_column(Text) + query_string: Mapped[Optional[str]] = mapped_column(Text) + request_method: Mapped[Optional[str]] = mapped_column(String(20)) + http_referer: Mapped[Optional[str]] = mapped_column(Text) + requestdata: Mapped[Optional[list[str]]] = mapped_column(ARRAY(Text()), comment='REQUEST') + sessiondata: Mapped[Optional[list[str]]] = mapped_column(ARRAY(Text()), comment='Daten Usersession') + +t_service_temp = Table( + 'service_temp', PortalObject.metadata, + Column('ukz', String(30)), + Column('request', Text) +) + +t_userliste = Table( + 'userliste', PortalObject.metadata, + Column('ukz', String(20)) +) + +__all__ = ['Eventlogadmin', 'Requestlog'] diff --git a/definitions/orm_views.py b/definitions/orm_views.py new file mode 100644 index 0000000..acfc989 --- /dev/null +++ b/definitions/orm_views.py @@ -0,0 +1,4 @@ +from risclog.claimxdb.database.base import PortalObject +from sqlalchemy import FetchedValue, text + +__all__ = [] diff --git a/definitions/pg_aggregates.py b/definitions/pg_aggregates.py new file mode 100644 index 0000000..d11c076 --- /dev/null +++ b/definitions/pg_aggregates.py @@ -0,0 +1,4 @@ +from alembic_utils.pg_aggregate import PGAggregate # noqa: I001 + + +all_aggregates = [] diff --git a/definitions/pg_extensions.py b/definitions/pg_extensions.py new file mode 100644 index 0000000..11184fd --- /dev/null +++ b/definitions/pg_extensions.py @@ -0,0 +1,4 @@ +from alembic_utils.pg_extension import PGExtension # noqa: I001 + + +all_extensions = [] diff --git a/definitions/pg_functions.py b/definitions/pg_functions.py new file mode 100644 index 0000000..7ee878a --- /dev/null +++ b/definitions/pg_functions.py @@ -0,0 +1,4 @@ +from alembic_utils.pg_function import PGFunction # noqa: I001 + + +all_functions = [] diff --git a/definitions/pg_policies.py b/definitions/pg_policies.py new file mode 100644 index 0000000..29d03e8 --- /dev/null +++ b/definitions/pg_policies.py @@ -0,0 +1,4 @@ +from alembic_utils.pg_policy import PGPolicy # noqa: I001 + + +all_policies = [] diff --git a/definitions/pg_publications.py b/definitions/pg_publications.py new file mode 100644 index 0000000..0d36447 --- /dev/null +++ b/definitions/pg_publications.py @@ -0,0 +1,4 @@ +from risclog.claimxdb.alembic.object_ops import PGPublication # noqa: I001 + + +all_publications = [] diff --git a/definitions/pg_seeds.py b/definitions/pg_seeds.py new file mode 100644 index 0000000..92fa60a --- /dev/null +++ b/definitions/pg_seeds.py @@ -0,0 +1,25 @@ + + +all_seeds = { + 'eventlog': [ + + ], + 'eventlogadmin': [ + + ], + 'eventmail': [ + + ], + 'userliste': [ + + ], + 'importlog': [ + + ], + 'service_temp': [ + + ], + 'requestlog': [ + + ], +} \ No newline at end of file diff --git a/definitions/pg_triggers.py b/definitions/pg_triggers.py new file mode 100644 index 0000000..3e8794d --- /dev/null +++ b/definitions/pg_triggers.py @@ -0,0 +1,4 @@ +from alembic_utils.pg_trigger import PGTrigger # noqa: I001 + + +all_triggers = [] diff --git a/src/sqlacodegen/cli.py b/src/sqlacodegen/cli.py index ce18d7a..9a65729 100644 --- a/src/sqlacodegen/cli.py +++ b/src/sqlacodegen/cli.py @@ -283,8 +283,9 @@ class ExportDict(TypedDict, total=False): orm_views, pg_alembic = gen_func(generator_views) # type: ignore[operator] with open(dest_orm_path, "w", encoding="utf-8") as f: f.write(orm_views) - with open(dest_pg_path, "w", encoding="utf-8") as f: - f.write("\n".join(pg_alembic)) + if pg_alembic: + with open(dest_pg_path, "w", encoding="utf-8") as f: + f.write("\n".join(pg_alembic)) print(f"{title} geschrieben nach: {dest_orm_path.as_posix()}") else: generator_views = generator_class(metadata_views, engine, options) From f99b6bac9c2e8d6375ff8708e763500948bcf461 Mon Sep 17 00:00:00 2001 From: Marcus Steinbach Date: Tue, 26 Aug 2025 06:39:12 +0200 Subject: [PATCH 2/2] feat: added free sequences entities --- definitions/orm_tables.py | 102 -------------------------- definitions/orm_views.py | 4 - definitions/pg_aggregates.py | 4 - definitions/pg_extensions.py | 4 - definitions/pg_functions.py | 4 - definitions/pg_policies.py | 4 - definitions/pg_publications.py | 4 - definitions/pg_seeds.py | 25 ------- definitions/pg_triggers.py | 4 - src/sqlacodegen/cli.py | 11 ++- src/sqlacodegen/risclog_generators.py | 59 +++++++++------ 11 files changed, 46 insertions(+), 179 deletions(-) delete mode 100644 definitions/orm_tables.py delete mode 100644 definitions/orm_views.py delete mode 100644 definitions/pg_aggregates.py delete mode 100644 definitions/pg_extensions.py delete mode 100644 definitions/pg_functions.py delete mode 100644 definitions/pg_policies.py delete mode 100644 definitions/pg_publications.py delete mode 100644 definitions/pg_seeds.py delete mode 100644 definitions/pg_triggers.py diff --git a/definitions/orm_tables.py b/definitions/orm_tables.py deleted file mode 100644 index 9be87ab..0000000 --- a/definitions/orm_tables.py +++ /dev/null @@ -1,102 +0,0 @@ -from typing import Optional - -from risclog.claimxdb.database.base import PortalObject -from sqlalchemy import ARRAY, Column, Date, DateTime, Double, FetchedValue, Index, Integer, Numeric, PrimaryKeyConstraint, String, Table, Text, Time, text -from sqlalchemy.orm import Mapped, mapped_column -import datetime - -t_eventlog = Table( - 'eventlog', PortalObject.metadata, - Column('eventid', Integer), - Column('eventtyp', String(30)), - Column('datum', Date), - Column('uhrzeit', DateTime), - Column('ukz', String(20)), - Column('fktname', String(50)), - Column('man', String(4)), - Column('request', Text), - Column('errortype', String(255)), - Column('errorvalue', Text), - Column('traceback', Text), - Column('skriptname', String(50)), - Column('details', Text), - Column('scode', Text), - Index('i_ev_tagesdatum', 'eventtyp', 'datum', postgresql_using=False) -) - -class Eventlogadmin(PortalObject): # type: ignore[misc] - __tablename__ = 'eventlogadmin' - __table_args__ = ( - PrimaryKeyConstraint('eventtyp', name='eventlogadmin_pkey'), - {'comment': 'Admin Event-Log'} - ) - - eventtyp: Mapped[str] = mapped_column(String(30), primary_key=True, comment='Eventtyp') - ignored_exceptions: Mapped[Optional[str]] = mapped_column(Text, comment='Ignored exceptions, getrennt durch CR') - -t_eventmail = Table( - 'eventmail', PortalObject.metadata, - Column('eventtyp', String(30)), - Column('skriptname', String(50)), - Column('fktname', String(50)), - Column('errortype', String(255)) -) - -t_importlog = Table( - 'importlog', PortalObject.metadata, - Column('ukz', String(20), comment='Fuhrparkimport Hochladender Benutzer'), - Column('man', String(4), comment='Fuhrparkimport angegebener Import-Mandant'), - Column('importdat', Date, comment='Fuhrparkimport Importdatum'), - Column('file', String(255), comment='Fuhrparkimport Pfad zur Quelldatei'), - Column('dl', String(30), comment='Fuhrparkimport angegebener Dienstleister - Import-Schema'), - Column('typ', String(20), comment='Fuhrparkimport Art Fahrzeuge / Fahrer'), - Column('info', Text, comment='Fuhrparkimport Fehler/Ereignisse/Hinweise'), - Column('status', String(30), comment='Fuhrparkimport status - Importiert ?'), - Column('cnt', Integer, comment='Fuhrparkimport Anzahl importierter Zeilen'), - Column('importid', Integer), - Column('zas', Text, comment='Sendungsdatenschnittstelle'), - Column('abrufdat', DateTime, comment='Datum des Sendungsdatumsabrufes'), - Column('sndnr', Text, comment='Sendungsdatum'), - Column('produkt', String(20), comment='Produkt'), - Column('zasinfo', String(30), comment='Zusatzinfo ZAS'), - Column('dtyp', String(1), comment='Aktentyp: (S)chaden, (P)rotokoll'), - Column('snddat', Date), - Column('abrufsec', Double(53), comment='Abrufdauer in sec'), - Column('fzgid', String(20)), - comment='Fehlerlog Fuhrparkimport' -) - -class Requestlog(PortalObject): # type: ignore[misc] - __tablename__ = 'requestlog' - __table_args__ = ( - PrimaryKeyConstraint('logid', name='requestlog_pkey'), - Index('i_logdatum', 'datum', 'zeit', postgresql_using=False), - Index('i_logman', 'man', postgresql_using=False), - Index('i_logukz', 'ukz', 'datum', postgresql_using=False) - ) - - logid: Mapped[int] = mapped_column(Integer, primary_key=True) - ukz: Mapped[str] = mapped_column(String(20)) - man: Mapped[str] = mapped_column(String(4)) - zopeid: Mapped[str] = mapped_column(String(50)) - datum: Mapped[datetime.date] = mapped_column(Date) - zeit: Mapped[datetime.time] = mapped_column(Time) - url: Mapped[Optional[str]] = mapped_column(Text) - query_string: Mapped[Optional[str]] = mapped_column(Text) - request_method: Mapped[Optional[str]] = mapped_column(String(20)) - http_referer: Mapped[Optional[str]] = mapped_column(Text) - requestdata: Mapped[Optional[list[str]]] = mapped_column(ARRAY(Text()), comment='REQUEST') - sessiondata: Mapped[Optional[list[str]]] = mapped_column(ARRAY(Text()), comment='Daten Usersession') - -t_service_temp = Table( - 'service_temp', PortalObject.metadata, - Column('ukz', String(30)), - Column('request', Text) -) - -t_userliste = Table( - 'userliste', PortalObject.metadata, - Column('ukz', String(20)) -) - -__all__ = ['Eventlogadmin', 'Requestlog'] diff --git a/definitions/orm_views.py b/definitions/orm_views.py deleted file mode 100644 index acfc989..0000000 --- a/definitions/orm_views.py +++ /dev/null @@ -1,4 +0,0 @@ -from risclog.claimxdb.database.base import PortalObject -from sqlalchemy import FetchedValue, text - -__all__ = [] diff --git a/definitions/pg_aggregates.py b/definitions/pg_aggregates.py deleted file mode 100644 index d11c076..0000000 --- a/definitions/pg_aggregates.py +++ /dev/null @@ -1,4 +0,0 @@ -from alembic_utils.pg_aggregate import PGAggregate # noqa: I001 - - -all_aggregates = [] diff --git a/definitions/pg_extensions.py b/definitions/pg_extensions.py deleted file mode 100644 index 11184fd..0000000 --- a/definitions/pg_extensions.py +++ /dev/null @@ -1,4 +0,0 @@ -from alembic_utils.pg_extension import PGExtension # noqa: I001 - - -all_extensions = [] diff --git a/definitions/pg_functions.py b/definitions/pg_functions.py deleted file mode 100644 index 7ee878a..0000000 --- a/definitions/pg_functions.py +++ /dev/null @@ -1,4 +0,0 @@ -from alembic_utils.pg_function import PGFunction # noqa: I001 - - -all_functions = [] diff --git a/definitions/pg_policies.py b/definitions/pg_policies.py deleted file mode 100644 index 29d03e8..0000000 --- a/definitions/pg_policies.py +++ /dev/null @@ -1,4 +0,0 @@ -from alembic_utils.pg_policy import PGPolicy # noqa: I001 - - -all_policies = [] diff --git a/definitions/pg_publications.py b/definitions/pg_publications.py deleted file mode 100644 index 0d36447..0000000 --- a/definitions/pg_publications.py +++ /dev/null @@ -1,4 +0,0 @@ -from risclog.claimxdb.alembic.object_ops import PGPublication # noqa: I001 - - -all_publications = [] diff --git a/definitions/pg_seeds.py b/definitions/pg_seeds.py deleted file mode 100644 index 92fa60a..0000000 --- a/definitions/pg_seeds.py +++ /dev/null @@ -1,25 +0,0 @@ - - -all_seeds = { - 'eventlog': [ - - ], - 'eventlogadmin': [ - - ], - 'eventmail': [ - - ], - 'userliste': [ - - ], - 'importlog': [ - - ], - 'service_temp': [ - - ], - 'requestlog': [ - - ], -} \ No newline at end of file diff --git a/definitions/pg_triggers.py b/definitions/pg_triggers.py deleted file mode 100644 index 3e8794d..0000000 --- a/definitions/pg_triggers.py +++ /dev/null @@ -1,4 +0,0 @@ -from alembic_utils.pg_trigger import PGTrigger # noqa: I001 - - -all_triggers = [] diff --git a/src/sqlacodegen/cli.py b/src/sqlacodegen/cli.py index 9a65729..8e39b80 100644 --- a/src/sqlacodegen/cli.py +++ b/src/sqlacodegen/cli.py @@ -32,6 +32,7 @@ parse_policy_row, parse_publication_row, parse_trigger_row, + parse_sequence_row, ) from sqlacodegen.seed_export import export_pgdata_py @@ -253,6 +254,14 @@ class ExportDict(TypedDict, total=False): "parse_row_func": parse_publication_row, "file": "pg_publications.py", }, + { + "title": "Sequences", + "entities_varname": "all_sequences", + "template": "ALEMBIC_SEQUENCE_TEMPLATE", + "statement": "ALEMBIC_STANDALONE_SEQUENCE_STATEMENT", + "parse_row_func": parse_sequence_row, + "file": "pg_sequence.py", + }, ] # ----------- Export-Loop ------------ @@ -283,7 +292,7 @@ class ExportDict(TypedDict, total=False): orm_views, pg_alembic = gen_func(generator_views) # type: ignore[operator] with open(dest_orm_path, "w", encoding="utf-8") as f: f.write(orm_views) - if pg_alembic: + if pg_alembic: with open(dest_pg_path, "w", encoding="utf-8") as f: f.write("\n".join(pg_alembic)) print(f"{title} geschrieben nach: {dest_orm_path.as_posix()}") diff --git a/src/sqlacodegen/risclog_generators.py b/src/sqlacodegen/risclog_generators.py index 2d758cb..d394b32 100644 --- a/src/sqlacodegen/risclog_generators.py +++ b/src/sqlacodegen/risclog_generators.py @@ -239,34 +239,47 @@ class {classname}(PortalObject): # type: ignore[misc] ORDER BY extname; """ -ALEMBIC_SEQUENCE_STATEMENT = """ +ALEMBIC_STANDALONE_SEQUENCE_STATEMENT = """ +WITH seqs AS ( + SELECT c.oid AS seq_oid, + n.nspname AS schema, + c.relname AS sequence_name + FROM pg_class c + JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind = 'S' + AND n.nspname NOT IN ('pg_catalog','information_schema') + AND n.nspname NOT LIKE 'pg_toast%' + AND n.nspname NOT LIKE 'pg_temp_%' +) SELECT - s.sequence_schema AS schema, - s.sequence_name, - s.data_type, - s.start_value, - s.minimum_value, - s.maximum_value, - s.increment, - s.cycle_option AS cycle, - ps.cache_size -FROM information_schema.sequences s + s.schema, + s.sequence_name, + ps.data_type, + ps.start_value, + ps.min_value AS minimum_value, + ps.max_value AS maximum_value, + ps.increment_by AS increment, + ps.cycle, + ps.cache_size +FROM seqs s JOIN pg_catalog.pg_sequences ps - ON s.sequence_schema = ps.schemaname - AND s.sequence_name = ps.sequencename -JOIN pg_class t - ON t.relkind = 'r' AND t.relnamespace = (SELECT oid FROM pg_namespace WHERE nspname = s.sequence_schema) -JOIN pg_attribute a - ON a.attrelid = t.oid -JOIN pg_attrdef d - ON d.adrelid = t.oid AND d.adnum = a.attnum -WHERE - s.sequence_schema NOT IN ('pg_catalog', 'information_schema') - AND pg_get_expr(d.adbin, d.adrelid) LIKE '%nextval(%' || s.sequence_name || '%' -ORDER BY s.sequence_schema, s.sequence_name; + ON ps.schemaname = s.schema + AND ps.sequencename = s.sequence_name +LEFT JOIN pg_depend owned + ON owned.classid = 'pg_class'::regclass + AND owned.objid = s.seq_oid + AND owned.deptype IN ('a','i') -- serial/identity ownership +LEFT JOIN pg_depend used + ON used.refclassid = 'pg_class'::regclass + AND used.refobjid = s.seq_oid + AND used.classid = 'pg_attrdef'::regclass -- used in a column DEFAULT +WHERE owned.objid IS NULL + AND used.objid IS NULL +ORDER BY s.schema, s.sequence_name; """ + def parse_publication_row( row: dict[str, Any], template_def: str,