tai-sql 0.7.14__tar.gz → 0.7.16__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tai_sql-0.7.16/LICENSE +32 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/PKG-INFO +8 -8
- {tai_sql-0.7.14 → tai_sql-0.7.16}/README.md +2 -2
- {tai_sql-0.7.14 → tai_sql-0.7.16}/pyproject.toml +9 -11
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_init/model.py +1 -1
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_schema/schemas/auth.py +14 -2
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/services/backup.py +4 -7
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/context.py +57 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/domain/model.py.jinja2 +4 -1
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/schema.py +2 -1
- tai_sql-0.7.14/LICENSE +0 -674
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_backup/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_backup/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_deploy/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_deploy/config.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_deploy/local.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_deploy/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_deploy/workflow.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_feed/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_feed/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_generate/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_generate/funcs.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_generate/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_hash_migrate/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_hash_migrate/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_info/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_info/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_info/status.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_init/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_init/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_install/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_install/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_ping/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_ping/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_pull/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_pull/funcs.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_pull/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_restore/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_restore/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_rules/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_rules/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_schema/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_schema/model.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_schema/new.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_schema/schemas/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_schema/schemas/base.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_schema/schemas/chatbot.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_schema/schemas/default.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/cmd_schema/set_default.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/prompts.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/utils/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/utils/connectivity.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/utils/create.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/utils/github/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/utils/github/auth.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/utils/github/client.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/commands/utils/github/models.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/errors.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/main.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/preamble.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/cli/services/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/connection/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/connection/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/connection/provider.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/connection/recipe.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/connection/session.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/connection/sources.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/crypto.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/drivers/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/drivers/base.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/drivers/bigquery.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/drivers/capabilities.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/drivers/mysql.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/drivers/postgresql.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/drivers/sqlserver.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/errors/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/errors/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/errors/collector.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/errors/render.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/errors/types.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/feed/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/feed/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/feed/collect.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/feed/executor.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/feed/feeder.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/feed/plan.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/feed/presenter.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/feed/records.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/feed/transform.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/base.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/assets/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/assets/cytoscape.min.js +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/builder.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/generator.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/graphviz_render.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/html_render.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/layout.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/model.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/templates/er.html.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/diagram/themes.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/calculated.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/base.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/domain/__init__.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/domain/dao.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/domain/dtos.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/facade.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/macros/aggregation.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/macros/dataframe.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/macros/filters.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/macros/hierarchy.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/macros/read.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/macros/triggers.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/macros/upsert.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/macros/vector.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/macros/write.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/session.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/shared/__init__.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/shared/aggregation.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/shared/context.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/shared/utils/__init__.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/shared/utils/encoders.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/shared/utils/funcs.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/shared/utils/hierarchy.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/shared/utils/rls.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/shared/vector.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/triggers/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/triggers/analyzer.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/triggers/renderer.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/triggers/steps.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/triggers/transformer.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/rules/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/rules/templates/schema.md.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/blueprint.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/build.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/defaults.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/naming.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/reader.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/templates/schema.py.jinja2 +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/types.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/introspect/writer.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/analysis/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/analysis/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/analysis/calculated.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/analysis/collector.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/analysis/column_analyzer.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/analysis/constraints.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/analysis/hints.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/analysis/relation_analyzer.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/analysis/schema_analyzer.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/annotations.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/base.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/calculated.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/columns.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/constraints.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/datasource.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/descriptors.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/encoders.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/enumerations.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/relations.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/table.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/trigger_api.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/triggers.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/declarative/view.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/mapping/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/mapping/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/mapping/sqlalchemy_mapper.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/model/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/model/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/model/column.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/model/constraints.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/model/entity.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/model/enumeration.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/model/relation.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/model/schema.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/model/trigger.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/naming.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/ordering.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/registry.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/orm/types.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/project/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/project/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/project/config.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/project/context.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/project/manager.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/project/paths.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/catalog.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/installer.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/meta.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/service.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/staleness.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/static/comandos.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/static/errores.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/rules/static/modelo.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/README.md +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/diff/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/diff/constraints.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/diff/indexes.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/diff/tables.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/diff/views.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/executor.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/ownership.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/plan/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/plan/planner.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/plan/statements.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/presenter.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/report.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/safety.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/state/__init__.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/state/local.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/state/model.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/state/normalize.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/state/remote.py +0 -0
- {tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/sync/synchronizer.py +0 -0
tai_sql-0.7.16/LICENSE
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
Licencia propietaria
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-2026 Triple Alpha Innovation. Todos los derechos reservados.
|
|
4
|
+
|
|
5
|
+
tai-sql (el «Software»), incluidos su código fuente, su código objeto, su
|
|
6
|
+
documentación y cualquier material asociado, es propiedad exclusiva de Triple
|
|
7
|
+
Alpha Innovation y está protegido por la legislación de propiedad intelectual e
|
|
8
|
+
industrial aplicable.
|
|
9
|
+
|
|
10
|
+
No se concede ninguna licencia ni ningún otro derecho sobre el Software, de
|
|
11
|
+
forma expresa o implícita, salvo los que Triple Alpha Innovation otorgue por
|
|
12
|
+
escrito. En particular, sin esa autorización previa y por escrito queda
|
|
13
|
+
prohibido:
|
|
14
|
+
|
|
15
|
+
1. usar, ejecutar o instalar el Software;
|
|
16
|
+
2. copiar, reproducir o modificar el Software, total o parcialmente;
|
|
17
|
+
3. distribuir, publicar, sublicenciar, ceder, alquilar o vender el Software o
|
|
18
|
+
cualquier obra derivada de él;
|
|
19
|
+
4. descompilar, desensamblar o aplicar ingeniería inversa al Software, salvo
|
|
20
|
+
en los casos en que la ley lo permita expresamente.
|
|
21
|
+
|
|
22
|
+
El acceso al Software o su obtención por cualquier medio, incluidos los
|
|
23
|
+
repositorios públicos de paquetes, no implica la concesión de ninguna licencia.
|
|
24
|
+
|
|
25
|
+
EL SOFTWARE SE PROPORCIONA «TAL CUAL», SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O
|
|
26
|
+
IMPLÍCITA, INCLUIDAS, SIN LIMITACIÓN, LAS GARANTÍAS DE COMERCIABILIDAD, IDONEIDAD
|
|
27
|
+
PARA UN FIN DETERMINADO Y NO INFRACCIÓN. EN NINGÚN CASO TRIPLE ALPHA INNOVATION
|
|
28
|
+
SERÁ RESPONSABLE DE NINGUNA RECLAMACIÓN, DAÑO U OTRA RESPONSABILIDAD DERIVADA DEL
|
|
29
|
+
SOFTWARE O DE SU USO, SALVO EN LO QUE ESTABLEZCA EL ACUERDO ESCRITO QUE AUTORICE
|
|
30
|
+
ESE USO.
|
|
31
|
+
|
|
32
|
+
Para solicitar autorización: Triple Alpha Innovation, https://www.triplealpha.in/
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tai-sql
|
|
3
|
-
Version: 0.7.
|
|
3
|
+
Version: 0.7.16
|
|
4
4
|
Summary: SQL database management and code generation tool
|
|
5
|
-
License-Expression:
|
|
5
|
+
License-Expression: LicenseRef-Proprietary
|
|
6
6
|
License-File: LICENSE
|
|
7
7
|
Keywords: sql,database,code-generation,orm,sqlalchemy
|
|
8
8
|
Author: MateoSaezMata
|
|
@@ -51,10 +51,10 @@ Requires-Dist: rich (>=15.0.0,<16.0.0)
|
|
|
51
51
|
Requires-Dist: sqlalchemy (>=2.0.42,<3.0)
|
|
52
52
|
Requires-Dist: sqlalchemy-bigquery (>=1.11.0,<2.0) ; extra == "all"
|
|
53
53
|
Requires-Dist: sqlalchemy-bigquery (>=1.11.0,<2.0) ; extra == "bigquery"
|
|
54
|
-
Requires-Dist: tai-alphi (>=2.0
|
|
55
|
-
Requires-Dist: tai-alphi (>=2.0
|
|
56
|
-
Requires-Dist: tai-storage (>=0.
|
|
57
|
-
Requires-Dist: tai-storage (>=0.
|
|
54
|
+
Requires-Dist: tai-alphi (>=2.1.0,<3.0) ; extra == "all"
|
|
55
|
+
Requires-Dist: tai-alphi (>=2.1.0,<3.0) ; extra == "backup"
|
|
56
|
+
Requires-Dist: tai-storage (>=0.2.0,<0.3) ; extra == "all"
|
|
57
|
+
Requires-Dist: tai-storage (>=0.2.0,<0.3) ; extra == "backup"
|
|
58
58
|
Project-URL: Documentation, https://triplealpha-innovation.github.io/tai-sql/
|
|
59
59
|
Project-URL: Homepage, https://www.triplealpha.in/es/
|
|
60
60
|
Project-URL: Issues, https://github.com/triplealpha-innovation/tai-sql/issues
|
|
@@ -65,7 +65,7 @@ Description-Content-Type: text/markdown
|
|
|
65
65
|
|
|
66
66
|
[](https://pypi.org/project/tai-sql/)
|
|
67
67
|
[](https://pypi.org/project/tai-sql/)
|
|
68
|
-
[](LICENSE)
|
|
69
69
|
[](https://triplealpha-innovation.github.io/tai-sql/)
|
|
70
70
|
|
|
71
71
|
**Framework declarativo de Python, sobre SQLAlchemy, que gestiona el ciclo de vida completo de
|
|
@@ -248,7 +248,7 @@ Cada uno de esos paquetes tiene su propio `README.md` con el detalle.
|
|
|
248
248
|
|
|
249
249
|
## Licencia
|
|
250
250
|
|
|
251
|
-
|
|
251
|
+
Propietaria: © Triple Alpha Innovation, todos los derechos reservados. Ver [LICENSE](LICENSE).
|
|
252
252
|
|
|
253
253
|
---
|
|
254
254
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/tai-sql/)
|
|
4
4
|
[](https://pypi.org/project/tai-sql/)
|
|
5
|
-
[](LICENSE)
|
|
6
6
|
[](https://triplealpha-innovation.github.io/tai-sql/)
|
|
7
7
|
|
|
8
8
|
**Framework declarativo de Python, sobre SQLAlchemy, que gestiona el ciclo de vida completo de
|
|
@@ -185,7 +185,7 @@ Cada uno de esos paquetes tiene su propio `README.md` con el detalle.
|
|
|
185
185
|
|
|
186
186
|
## Licencia
|
|
187
187
|
|
|
188
|
-
|
|
188
|
+
Propietaria: © Triple Alpha Innovation, todos los derechos reservados. Ver [LICENSE](LICENSE).
|
|
189
189
|
|
|
190
190
|
---
|
|
191
191
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tai-sql"
|
|
3
|
-
version = "0.7.
|
|
3
|
+
version = "0.7.16"
|
|
4
4
|
description = "SQL database management and code generation tool"
|
|
5
|
-
license = "
|
|
5
|
+
license = "LicenseRef-Proprietary"
|
|
6
6
|
license-files = ["LICENSE"]
|
|
7
7
|
authors = [
|
|
8
8
|
{name = "MateoSaezMata", email = "msaez@triplealpha.in"},
|
|
@@ -99,7 +99,7 @@ diagrams = ["graphviz>=0.20.3,<1.0"]
|
|
|
99
99
|
# `deploy`: nada hoy — el comando está **desactivado a propósito** (comentado en
|
|
100
100
|
# `cli/main.py`). El extra se conserva para no romper a quien lo tenga instalado, pero
|
|
101
101
|
# instalarlo no habilita ningún comando.
|
|
102
|
-
backup = ["tai-storage>=0.
|
|
102
|
+
backup = ["tai-storage>=0.2.0,<0.3", "tai-alphi>=2.1.0,<3.0"]
|
|
103
103
|
deploy = ["requests>=2.32.4,<3.0", "pynacl>=1.5.0,<2.0"]
|
|
104
104
|
|
|
105
105
|
# ── Todo ──────────────────────────────────────────────────────────────────────
|
|
@@ -115,8 +115,8 @@ all = [
|
|
|
115
115
|
"cryptography>=45.0.4,<46.0",
|
|
116
116
|
"bcrypt>=4.0.0,<6.0",
|
|
117
117
|
"graphviz>=0.20.3,<1.0",
|
|
118
|
-
"tai-storage>=0.
|
|
119
|
-
"tai-alphi>=2.0
|
|
118
|
+
"tai-storage>=0.2.0,<0.3",
|
|
119
|
+
"tai-alphi>=2.1.0,<3.0",
|
|
120
120
|
"requests>=2.32.4,<3.0",
|
|
121
121
|
"pynacl>=1.5.0,<2.0",
|
|
122
122
|
]
|
|
@@ -125,7 +125,7 @@ all = [
|
|
|
125
125
|
tai-sql = "tai_sql.cli.main:cli"
|
|
126
126
|
|
|
127
127
|
[build-system]
|
|
128
|
-
# poetry-core 2 hace falta para `license
|
|
128
|
+
# poetry-core 2 hace falta para `license` como expresión SPDX (PEP 639).
|
|
129
129
|
requires = ["poetry-core>=2.0.0,<3.0.0"]
|
|
130
130
|
build-backend = "poetry.core.masonry.api"
|
|
131
131
|
|
|
@@ -147,11 +147,9 @@ dev = [
|
|
|
147
147
|
# lo que hay que poder afirmar es que el código que se despliega está probado.
|
|
148
148
|
# Ver `tests/_client_coverage.py`.
|
|
149
149
|
"coverage (>=7.0)",
|
|
150
|
-
# No lo importa tai-sql: lo
|
|
151
|
-
# `from_dataframe`) y
|
|
152
|
-
#
|
|
153
|
-
# `backup` y **la colección de toda la suite se rompía** al importarlo, mientras en
|
|
154
|
-
# local pasaba porque pandas estaba instalado sin que nadie lo hubiera pedido.
|
|
150
|
+
# No lo importa tai-sql: lo importa el cliente generado (`as_dataframe`,
|
|
151
|
+
# `from_dataframe`), y sus tests lo ejercitan. Hasta tai-storage 0.1.16 también lo
|
|
152
|
+
# exigía `import tai_storage` (cargaba su submódulo `data`); desde la 0.2 ya no.
|
|
155
153
|
"pandas (>=2.0,<3.0)",
|
|
156
154
|
# Lo mismo por el otro lado: `test_generated_runtime.py` ejercita el cliente async
|
|
157
155
|
# contra PostgreSQL, y su dialecto es asyncpg. Sin declararlo, esos 22 tests pasaban
|
|
@@ -16,7 +16,7 @@ class AuthSchema(SchemaTemplate):
|
|
|
16
16
|
Modela un control de acceso multi-realm — cada Realm agrupa sus propios
|
|
17
17
|
usuarios y roles, y las tablas puente UserRole/RolePermission resuelven las
|
|
18
18
|
relaciones muchos-a-muchos. Los roles admiten anidamiento vía
|
|
19
|
-
`parent_role_name
|
|
19
|
+
`parent_role_name`: una FK compuesta que obliga a que el padre sea del mismo realm.
|
|
20
20
|
|
|
21
21
|
Requisitos:
|
|
22
22
|
- Variable de entorno MAIN_DATABASE_URL con la conexión.
|
|
@@ -80,6 +80,7 @@ class AuthSchema(SchemaTemplate):
|
|
|
80
80
|
users: onetomany[User]
|
|
81
81
|
roles: onetomany[Role]
|
|
82
82
|
permissions: onetomany[Permission]
|
|
83
|
+
rls_rules: onetomany[RowLevelSecurity]
|
|
83
84
|
|
|
84
85
|
def feed(self) -> list:
|
|
85
86
|
return [
|
|
@@ -145,9 +146,17 @@ class AuthSchema(SchemaTemplate):
|
|
|
145
146
|
description: col[str | None] = column(description="Descripción del rol")
|
|
146
147
|
attributes: col[dict | None] = column(description="Atributos adicionales del rol (JSON)")
|
|
147
148
|
|
|
148
|
-
parent_role_name: col[str | None] = column(description="
|
|
149
|
+
parent_role_name: col[str | None] = column(description="Rol padre, del mismo realm, para subroles (roles anidados)")
|
|
149
150
|
|
|
150
151
|
realm: manytoone[Realm] = relation(fields=["realm_name"], references=["name"], backref="roles")
|
|
152
|
+
# El padre es del mismo realm porque la clave lo dice: la FK es compuesta y
|
|
153
|
+
# comparte `realm_name`. Con `self_reference="name"` la jerarquía no tenía FK y
|
|
154
|
+
# se resolvía solo por nombre, así que un padre podía no existir o ser otro rol
|
|
155
|
+
# homónimo de otro realm. `restrict`: borrar un rol con subroles es un error,
|
|
156
|
+
# no una cascada que se los lleve (y `set null` vaciaría también `realm_name`).
|
|
157
|
+
parent: manytoone[Role] = relation(fields=["parent_role_name", "realm_name"], references=["name", "realm_name"], backref="subroles", onDelete="restrict")
|
|
158
|
+
|
|
159
|
+
subroles: onetomany[Role]
|
|
151
160
|
|
|
152
161
|
role_permissions: onetomany[RolePermission]
|
|
153
162
|
user_roles: onetomany[UserRole]
|
|
@@ -248,6 +257,9 @@ class AuthSchema(SchemaTemplate):
|
|
|
248
257
|
table_name: col[str] = column(primary_key=True, description="Nombre de la tabla a la que aplica la regla RLS")
|
|
249
258
|
column_name: col[str] = column(primary_key=True, description="Nombre de la columna a la que se le aplica la regla RLS")
|
|
250
259
|
|
|
260
|
+
# Una regla es de un realm: sin la FK, borrar el realm dejaba sus reglas sueltas.
|
|
261
|
+
realm: manytoone[Realm] = relation(fields=["realm_name"], references=["name"], backref="rls_rules")
|
|
262
|
+
|
|
251
263
|
''').strip()
|
|
252
264
|
|
|
253
265
|
def create_views(self, views_dir: Path) -> None:
|
|
@@ -7,6 +7,7 @@ import re
|
|
|
7
7
|
import shutil
|
|
8
8
|
import subprocess
|
|
9
9
|
import tempfile
|
|
10
|
+
from pathlib import Path
|
|
10
11
|
from datetime import datetime
|
|
11
12
|
from typing import List, Optional
|
|
12
13
|
|
|
@@ -153,10 +154,8 @@ class BackupService:
|
|
|
153
154
|
msg = _parse_stderr(result.stderr, 'backup')
|
|
154
155
|
raise RuntimeError(f"Falló el backup con {tool}:\n {msg}")
|
|
155
156
|
|
|
156
|
-
# Subir al storage
|
|
157
|
-
|
|
158
|
-
with open(tmp_path, 'rb') as f:
|
|
159
|
-
folder.upload_file(f.read(), filename)
|
|
157
|
+
# Subir al storage: desde la ruta, por trozos, sin cargar el volcado en memoria
|
|
158
|
+
origin.get_folder('.').upload_file(Path(tmp_path), filename)
|
|
160
159
|
|
|
161
160
|
# Aplicar retención
|
|
162
161
|
if self.sm.backup_retention is not None:
|
|
@@ -183,9 +182,7 @@ class BackupService:
|
|
|
183
182
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
184
183
|
tmp_path = os.path.join(tmpdir, filename)
|
|
185
184
|
|
|
186
|
-
|
|
187
|
-
with open(tmp_path, 'wb') as f:
|
|
188
|
-
f.write(data)
|
|
185
|
+
file.download_to_local(tmp_path)
|
|
189
186
|
|
|
190
187
|
target = self.sm.restore_provider
|
|
191
188
|
|
|
@@ -329,8 +329,65 @@ class TemplateContextBuilder:
|
|
|
329
329
|
# clase destino tal y como el usuario la escribió.
|
|
330
330
|
'description': (target.declared_by.__doc__ or '') if target.declared_by else '',
|
|
331
331
|
'target_has_create_triggers': self._has_create_triggers(relation.target),
|
|
332
|
+
'overlaps': self._overlaps(relation),
|
|
333
|
+
'remote_side': self._remote_side(relation),
|
|
332
334
|
}
|
|
333
335
|
|
|
336
|
+
@staticmethod
|
|
337
|
+
def _remote_side(relation: RelationModel) -> List[str]:
|
|
338
|
+
"""
|
|
339
|
+
Las columnas del padre en una relación de una tabla consigo misma.
|
|
340
|
+
|
|
341
|
+
Si `local` y `target` son la misma clase, SQLAlchemy no puede deducir qué lado es
|
|
342
|
+
el padre —las dos puntas son la misma tabla— y rechaza la pareja por tener la
|
|
343
|
+
misma dirección. En el lado que posee la FK, el remoto son las columnas
|
|
344
|
+
referenciadas: es la *composite adjacency list* de la documentación de SQLAlchemy,
|
|
345
|
+
y vale también cuando la FK comparte una columna con la PK (`realm_name` en
|
|
346
|
+
`Role.parent`). El lado inverso no lo necesita: lo deduce del `back_populates`.
|
|
347
|
+
"""
|
|
348
|
+
owns_fk = relation.direction == 'many-to-one' or (
|
|
349
|
+
relation.is_one_to_one and not relation.implicit
|
|
350
|
+
)
|
|
351
|
+
if relation.local != relation.target or not owns_fk:
|
|
352
|
+
return []
|
|
353
|
+
return [f'{relation.target}.{ref}' for ref in relation.references]
|
|
354
|
+
|
|
355
|
+
def _overlaps(self, relation: RelationModel) -> List[str]:
|
|
356
|
+
"""
|
|
357
|
+
Relaciones que escriben alguna de las columnas FK de ésta.
|
|
358
|
+
|
|
359
|
+
Dos claves foráneas compuestas pueden compartir una columna: en un schema
|
|
360
|
+
multi-tenant, `UserRole(user_name, realm_name) → User` y
|
|
361
|
+
`UserRole(role_name, realm_name) → Role` comparten `realm_name`, y esa
|
|
362
|
+
columna compartida es justo lo que obliga a que usuario y rol sean del mismo
|
|
363
|
+
realm. Es intencionado, pero SQLAlchemy no lo sabe: al configurar los mappers
|
|
364
|
+
avisa de que las dos relaciones copiarían valores a la misma columna. Se le
|
|
365
|
+
dice con `overlaps=`, que en cada lado nombra las relaciones del otro.
|
|
366
|
+
|
|
367
|
+
La columna compartida vive en la tabla que posee la FK: en el lado explícito
|
|
368
|
+
es `local` y sus columnas son `fields`; en el implícito es `target`, y las
|
|
369
|
+
columnas, `references`.
|
|
370
|
+
"""
|
|
371
|
+
owns_fk = relation.direction == 'many-to-one' or (
|
|
372
|
+
relation.is_one_to_one and not relation.implicit
|
|
373
|
+
)
|
|
374
|
+
if owns_fk:
|
|
375
|
+
owner_name, columns, own = relation.local, relation.fields, relation.name
|
|
376
|
+
else:
|
|
377
|
+
owner_name, columns, own = relation.target, relation.references, relation.backref
|
|
378
|
+
|
|
379
|
+
owner = self.schema.entity(owner_name)
|
|
380
|
+
shared = set(columns)
|
|
381
|
+
names: set[str] = set()
|
|
382
|
+
for fk in getattr(owner, 'foreign_keys', ()):
|
|
383
|
+
if fk.relation == own or not shared & set(fk.local_columns):
|
|
384
|
+
continue
|
|
385
|
+
names.add(fk.relation)
|
|
386
|
+
other = owner.relations.get(fk.relation)
|
|
387
|
+
if other is not None and other.backref:
|
|
388
|
+
names.add(other.backref)
|
|
389
|
+
return sorted(names)
|
|
390
|
+
|
|
334
391
|
def foreign_key(self, fk: ForeignKeyModel) -> Dict[str, Any]:
|
|
335
392
|
"""
|
|
336
393
|
Contexto de una clave foránea.
|
{tai_sql-0.7.14 → tai_sql-0.7.16}/tai_sql/generators/python_client/templates/domain/model.py.jinja2
RENAMED
|
@@ -279,7 +279,8 @@ class {{ model.name }}(Base):
|
|
|
279
279
|
{# SQLAlchemy relationship() with:
|
|
280
280
|
- back_populates for bidirectional navigation
|
|
281
281
|
- foreign_keys as string expression to avoid circular import issues
|
|
282
|
-
- passive_deletes="all" on one-to-many to let the DB handle cascades
|
|
282
|
+
- passive_deletes="all" on one-to-many to let the DB handle cascades
|
|
283
|
+
- overlaps when two FKs share a column (context.py: _overlaps) #}
|
|
283
284
|
{% if model.relations | default([]) | list %}
|
|
284
285
|
{% for rel in model.relations %}
|
|
285
286
|
{% if rel.direction == "one-to-many" %}
|
|
@@ -294,6 +295,8 @@ class {{ model.name }}(Base):
|
|
|
294
295
|
{% set _ = rel_args.append('foreign_keys="[' + fk_parts | join(', ') + ']"') %}
|
|
295
296
|
{% if rel.direction == "one-to-many" %}{% set _ = rel_args.append('passive_deletes="all"') %}{% endif %}
|
|
296
297
|
{% if rel.direction == "one-to-one" %}{% set _ = rel_args.append('uselist=False') %}{% endif %}
|
|
298
|
+
{% if rel.remote_side %}{% set _ = rel_args.append('remote_side="[' + rel.remote_side | join(', ') + ']"') %}{% endif %}
|
|
299
|
+
{% if rel.overlaps %}{% set _ = rel_args.append('overlaps="' + rel.overlaps | join(',') + '"') %}{% endif %}
|
|
297
300
|
{{ rel.name }}: Mapped[{{ rel.target_type }}] = relationship({{ rel_args | join(', ') }})
|
|
298
301
|
{% endfor %}
|
|
299
302
|
{% endif %}
|
|
@@ -144,7 +144,8 @@ class SchemaManager:
|
|
|
144
144
|
if self._backup_storage is None:
|
|
145
145
|
from tai_storage import StorageFactory
|
|
146
146
|
from tai_alphi import Alphi
|
|
147
|
-
|
|
147
|
+
# Default de librería: la aplicación puede seguir ajustando el logger de tai-storage
|
|
148
|
+
Alphi.set_default_config('tai-storage', {'consola': {'log_level': 'ERROR'}})
|
|
148
149
|
root_path = f'.database_backups/{self.schema_name}'
|
|
149
150
|
self._backup_storage = StorageFactory.create_local(root_path=root_path)
|
|
150
151
|
return self._backup_storage
|