aury-boot 0.0.32__tar.gz → 0.0.34__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.
- {aury_boot-0.0.32 → aury_boot-0.0.34}/PKG-INFO +1 -1
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/_version.py +2 -2
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/generate/repository.py.tpl +3 -2
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/02-repository.md.tpl +36 -23
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/pagination/__init__.py +68 -70
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/repository/impl.py +103 -26
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/repository/interface.py +26 -7
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/__init__.py +2 -1
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/manager.py +54 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/.gitignore +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/README.md +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/adapter/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/adapter/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/adapter/config.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/adapter/decorators.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/adapter/exceptions.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/adapter/http.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/app/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/app/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/app/components.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/app/middlewares.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/app/startup.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/config/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/config/multi_instance.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/config/settings.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/constants/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/constants/components.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/constants/scheduler.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/constants/service.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/errors/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/errors/chain.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/errors/codes.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/errors/exceptions.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/errors/handlers.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/errors/response.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/interfaces/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/interfaces/egress.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/interfaces/ingress.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/middleware/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/middleware/logging.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/migrations/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/migrations/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/migrations/setup.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/rpc/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/rpc/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/rpc/client.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/rpc/discovery.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/scheduler/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/scheduler/runner.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/application/server/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/add.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/app.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/config.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/docker.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/docs.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/generate.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/init.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/migrate/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/migrate/app.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/migrate/commands.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/pkg.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/scheduler.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/server/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/server/app.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/generate/api.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/generate/model.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/generate/schema.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/generate/service.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/AGENTS.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/README.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/admin_console_init.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/alert_rules.example.yaml.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/00-overview.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/01-model.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/03-service.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/04-schema.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/05-api.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/06-exception.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/07-cache.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/08-scheduler.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/09-tasks.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/10-storage.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/11-logging.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/12-admin.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/13-channel.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/14-mq.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/15-events.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/16-adapter.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/17-alerting.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/aury_docs/99-cli.md.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/config.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/conftest.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/_header.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/admin.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/cache.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/database.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/log.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/messaging.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/monitoring.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/rpc.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/scheduler.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/service.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/storage.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/env_templates/third_party.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/gitignore.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/main.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/modules/api.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/modules/exceptions.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/modules/schedules.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/project/modules/tasks.py.tpl +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/worker.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/common/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/common/exceptions/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/common/i18n/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/common/i18n/translator.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/common/logging/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/common/logging/context.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/common/logging/decorators.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/common/logging/format.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/common/logging/setup.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/contrib/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/contrib/admin_console/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/contrib/admin_console/auth.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/contrib/admin_console/discovery.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/contrib/admin_console/install.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/contrib/admin_console/utils.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/exceptions/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/models/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/models/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/models/mixins.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/models/models.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/repository/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/repository/interceptors.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/repository/query_builder.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/service/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/service/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/domain/transaction/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/cache/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/cache/backends.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/cache/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/cache/exceptions.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/cache/factory.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/cache/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/channel/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/channel/backends/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/channel/backends/broadcaster.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/channel/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/channel/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/clients/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/clients/rabbitmq/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/clients/rabbitmq/config.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/clients/rabbitmq/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/clients/redis/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/clients/redis/config.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/clients/redis/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/database/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/database/config.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/database/exceptions.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/database/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/database/query_tools/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/database/strategies/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/di/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/di/container.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/events/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/events/backends/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/events/backends/broadcaster.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/events/backends/rabbitmq.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/events/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/events/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/events/middleware.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/aggregator.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/events.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/notifiers/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/notifiers/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/notifiers/feishu.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/notifiers/webhook.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/rules.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/health/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/tracing/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/tracing/context.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/tracing/logging.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/tracing/processor.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/tracing/provider.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/tracing/tracing.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/mq/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/mq/backends/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/mq/backends/rabbitmq.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/mq/backends/redis.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/mq/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/mq/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/scheduler/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/scheduler/exceptions.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/scheduler/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/storage/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/storage/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/storage/exceptions.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/storage/factory.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/tasks/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/tasks/config.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/tasks/constants.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/tasks/exceptions.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/tasks/manager.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/testing/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/testing/base.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/testing/client.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/testing/factory.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/toolkit/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/toolkit/http/__init__.py +0 -0
- {aury_boot-0.0.32 → aury_boot-0.0.34}/pyproject.toml +0 -0
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 0,
|
|
31
|
+
__version__ = version = '0.0.34'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 34)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
{aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/commands/templates/generate/repository.py.tpl
RENAMED
|
@@ -11,8 +11,9 @@ class {class_name}Repository(BaseRepository[{class_name}]):
|
|
|
11
11
|
继承 BaseRepository 自动获得:
|
|
12
12
|
- get(id): 按 ID 获取
|
|
13
13
|
- get_by(**filters): 按条件获取单个
|
|
14
|
-
- list(skip, limit, **filters): 获取列表
|
|
15
|
-
- paginate(
|
|
14
|
+
- list(skip, limit, sort, **filters): 获取列表
|
|
15
|
+
- paginate(pagination, sort, **filters): 分页获取
|
|
16
|
+
- stream(batch_size, sort, **filters): 流式查询
|
|
16
17
|
- create(data): 创建
|
|
17
18
|
- update(entity, data): 更新
|
|
18
19
|
- delete(entity, soft=True): 删除
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
**文件**: `{package_name}/repositories/user_repository.py`
|
|
6
6
|
|
|
7
7
|
```python
|
|
8
|
-
"""User 数据访问层。"""
|
|
8
|
+
"""“User 数据访问层。"""
|
|
9
9
|
|
|
10
10
|
from aury.boot.domain.repository.impl import BaseRepository
|
|
11
11
|
|
|
@@ -18,13 +18,14 @@ class UserRepository(BaseRepository[User]):
|
|
|
18
18
|
继承 BaseRepository 自动获得:
|
|
19
19
|
- get(id): 按 ID 获取
|
|
20
20
|
- get_by(**filters): 按条件获取单个
|
|
21
|
-
- list(skip, limit, **filters): 获取列表
|
|
22
|
-
- paginate(
|
|
21
|
+
- list(skip, limit, sort, **filters): 获取列表
|
|
22
|
+
- paginate(pagination, sort, **filters): 分页获取
|
|
23
23
|
- count(**filters): 计数
|
|
24
24
|
- exists(**filters): 是否存在
|
|
25
25
|
- create(data): 创建
|
|
26
26
|
- update(entity, data): 更新
|
|
27
27
|
- delete(entity, soft=True): 删除(默认软删除)
|
|
28
|
+
- stream(batch_size, sort, **filters): 流式查询
|
|
28
29
|
- batch_create(data_list): 批量创建
|
|
29
30
|
- bulk_insert(data_list): 高性能批量插入
|
|
30
31
|
"""
|
|
@@ -35,7 +36,7 @@ class UserRepository(BaseRepository[User]):
|
|
|
35
36
|
|
|
36
37
|
async def list_active(self, skip: int = 0, limit: int = 100) -> list[User]:
|
|
37
38
|
"""获取激活用户列表。"""
|
|
38
|
-
return await self.list(skip=skip, limit=limit, is_active=True)
|
|
39
|
+
return await self.list(skip=skip, limit=limit, sort="-created_at", is_active=True)
|
|
39
40
|
```
|
|
40
41
|
|
|
41
42
|
## 2.2 BaseRepository 方法详解
|
|
@@ -50,25 +51,36 @@ repo = UserRepository(session, User)
|
|
|
50
51
|
user = await repo.get(user_id) # 按 ID(支持 int/UUID)
|
|
51
52
|
user = await repo.get_by(email="a@b.com") # 按条件(简单 AND 过滤)
|
|
52
53
|
users = await repo.list(skip=0, limit=10) # 列表
|
|
54
|
+
users = await repo.list(sort="-created_at") # 带排序
|
|
53
55
|
users = await repo.list(is_active=True) # 带过滤
|
|
54
56
|
count = await repo.count(is_active=True) # 计数
|
|
55
57
|
exists = await repo.exists(email="a@b.com") # 是否存在
|
|
56
58
|
|
|
57
59
|
# === 分页 ===
|
|
58
|
-
from aury.boot.domain.pagination import PaginationParams
|
|
60
|
+
from aury.boot.domain.pagination import PaginationParams
|
|
59
61
|
|
|
62
|
+
# 方式1: offset/limit(与 SQL 语义一致)
|
|
60
63
|
result = await repo.paginate(
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
pagination=PaginationParams(offset=0, limit=20),
|
|
65
|
+
sort="-created_at",
|
|
66
|
+
is_active=True,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# 方式2: page/size(UI 风格)
|
|
70
|
+
result = await repo.paginate(
|
|
71
|
+
pagination=PaginationParams.of(page=1, size=20),
|
|
72
|
+
sort="-created_at",
|
|
63
73
|
is_active=True,
|
|
64
74
|
)
|
|
65
75
|
|
|
66
76
|
# PaginationResult 结构:
|
|
67
77
|
# - result.items: list[T] # 数据列表
|
|
68
78
|
# - result.total: int # 总记录数
|
|
69
|
-
# - result.
|
|
70
|
-
# - result.
|
|
71
|
-
# - result.
|
|
79
|
+
# - result.offset: int # 当前偏移量
|
|
80
|
+
# - result.limit: int # 每页数量
|
|
81
|
+
# - result.page: int # 当前页码(计算属性)
|
|
82
|
+
# - result.size: int # limit 别名
|
|
83
|
+
# - result.total_pages: int # 总页数(计算属性)
|
|
72
84
|
# - result.has_next: bool # 是否有下一页
|
|
73
85
|
# - result.has_prev: bool # 是否有上一页
|
|
74
86
|
|
|
@@ -96,11 +108,11 @@ result = await repo.cursor_paginate(
|
|
|
96
108
|
|
|
97
109
|
# === 流式查询(大数据处理) ===
|
|
98
110
|
# 逐条流式处理,不会一次性加载到内存
|
|
99
|
-
async for user in repo.stream(batch_size=1000, is_active=True):
|
|
111
|
+
async for user in repo.stream(batch_size=1000, sort="-created_at", is_active=True):
|
|
100
112
|
await process(user)
|
|
101
113
|
|
|
102
114
|
# 批量流式处理
|
|
103
|
-
async for batch in repo.stream_batches(batch_size=1000):
|
|
115
|
+
async for batch in repo.stream_batches(batch_size=1000, sort="id"):
|
|
104
116
|
await bulk_sync_to_es(batch)
|
|
105
117
|
|
|
106
118
|
# === 创建 ===
|
|
@@ -140,27 +152,28 @@ user = await repo.get_by(status__ne="archived")
|
|
|
140
152
|
|
|
141
153
|
> 注意:filters 条件之间用 AND 组合;如需 AND/OR/NOT 的复杂组合,请使用 `QueryBuilder`(见 2.4)。
|
|
142
154
|
|
|
143
|
-
### 2.2.2 排序参数(
|
|
155
|
+
### 2.2.2 排序参数(sort)
|
|
144
156
|
|
|
145
|
-
`
|
|
157
|
+
所有查询方法的 `sort` 参数支持多种格式:
|
|
146
158
|
|
|
147
159
|
```python
|
|
148
|
-
|
|
160
|
+
# 字符串(推荐)
|
|
161
|
+
await repo.list(sort="-created_at") # 简洁语法
|
|
162
|
+
await repo.list(sort="-created_at,priority") # 多字段
|
|
163
|
+
await repo.list(sort="created_at:desc,priority:asc") # 完整语法
|
|
149
164
|
|
|
150
|
-
#
|
|
151
|
-
|
|
152
|
-
sort_params = SortParams.from_string("-created_at,priority") # 多字段
|
|
165
|
+
# 字符串列表
|
|
166
|
+
await repo.list(sort=["-created_at", "name"])
|
|
153
167
|
|
|
154
|
-
#
|
|
155
|
-
|
|
168
|
+
# SortParams 对象(需要白名单验证时)
|
|
169
|
+
from aury.boot.domain.pagination import SortParams
|
|
156
170
|
|
|
157
|
-
# 带字段白名单验证(防止 SQL 注入)
|
|
158
171
|
ALLOWED_FIELDS = {{"id", "created_at", "priority", "status"}}
|
|
159
172
|
sort_params = SortParams.from_string(
|
|
160
173
|
"-created_at",
|
|
161
|
-
allowed_fields=ALLOWED_FIELDS
|
|
174
|
+
allowed_fields=ALLOWED_FIELDS # 传入非法字段抛 ValueError
|
|
162
175
|
)
|
|
163
|
-
|
|
176
|
+
await repo.list(sort=sort_params)
|
|
164
177
|
```
|
|
165
178
|
|
|
166
179
|
### 2.2.3 查询全部(limit=None)
|
|
@@ -14,61 +14,49 @@ from pydantic import BaseModel, Field, field_validator
|
|
|
14
14
|
class PaginationParams(BaseModel):
|
|
15
15
|
"""分页参数。
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
page: int = Field(default=1, ge=1, description="页码,从1开始")
|
|
21
|
-
page_size: int = Field(default=20, ge=1, le=100, description="每页记录数,最大100")
|
|
17
|
+
使用 offset/limit 模式,与 SQL 语义一致。
|
|
18
|
+
提供 `of()` 方法支持 page/size 风格的输入。
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
示例:
|
|
21
|
+
# 方式1: offset/limit(底层/API风格)
|
|
22
|
+
params = PaginationParams(offset=20, limit=10)
|
|
26
23
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return (self.page - 1) * self.page_size
|
|
24
|
+
# 方式2: page/size(UI风格)
|
|
25
|
+
params = PaginationParams.of(page=3, size=10)
|
|
26
|
+
"""
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
"""获取限制数量。
|
|
35
|
-
|
|
36
|
-
Returns:
|
|
37
|
-
int: 限制数量
|
|
38
|
-
"""
|
|
39
|
-
return self.page_size
|
|
28
|
+
offset: int = Field(default=0, ge=0, description="偏移量")
|
|
29
|
+
limit: int = Field(default=20, ge=1, le=100, description="每页记录数,最大100")
|
|
40
30
|
|
|
41
|
-
@field_validator("page")
|
|
42
31
|
@classmethod
|
|
43
|
-
def
|
|
44
|
-
"""
|
|
32
|
+
def of(cls, page: int = 1, size: int = 20) -> "PaginationParams":
|
|
33
|
+
"""从 page/size 构造分页参数。
|
|
45
34
|
|
|
46
35
|
Args:
|
|
47
|
-
|
|
36
|
+
page: 页码,从 1 开始
|
|
37
|
+
size: 每页记录数
|
|
48
38
|
|
|
49
39
|
Returns:
|
|
50
|
-
|
|
51
|
-
"""
|
|
52
|
-
if v < 1:
|
|
53
|
-
raise ValueError("页码必须大于0")
|
|
54
|
-
return v
|
|
55
|
-
|
|
56
|
-
@field_validator("page_size")
|
|
57
|
-
@classmethod
|
|
58
|
-
def validate_page_size(cls, v: int) -> int:
|
|
59
|
-
"""验证每页记录数。
|
|
60
|
-
|
|
61
|
-
Args:
|
|
62
|
-
v: 每页记录数
|
|
40
|
+
PaginationParams: 分页参数对象
|
|
63
41
|
|
|
64
|
-
|
|
65
|
-
|
|
42
|
+
Raises:
|
|
43
|
+
ValueError: 当 page < 1 或 size 无效时
|
|
66
44
|
"""
|
|
67
|
-
if
|
|
68
|
-
raise ValueError("
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
45
|
+
if page < 1:
|
|
46
|
+
raise ValueError("页码必须大于 0")
|
|
47
|
+
return cls(offset=(page - 1) * size, limit=size)
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def page(self) -> int:
|
|
51
|
+
"""当前页码(从 1 开始)。"""
|
|
52
|
+
if self.limit == 0:
|
|
53
|
+
return 1
|
|
54
|
+
return self.offset // self.limit + 1
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def size(self) -> int:
|
|
58
|
+
"""每页记录数(limit 的别名)。"""
|
|
59
|
+
return self.limit
|
|
72
60
|
|
|
73
61
|
|
|
74
62
|
class SortParams(BaseModel):
|
|
@@ -103,7 +91,7 @@ class SortParams(BaseModel):
|
|
|
103
91
|
sort_str: str | None,
|
|
104
92
|
*,
|
|
105
93
|
allowed_fields: set[str] | None = None,
|
|
106
|
-
default_direction: str = "
|
|
94
|
+
default_direction: str = "asc",
|
|
107
95
|
) -> SortParams:
|
|
108
96
|
"""从字符串解析排序参数。
|
|
109
97
|
|
|
@@ -124,7 +112,7 @@ class SortParams(BaseModel):
|
|
|
124
112
|
|
|
125
113
|
示例:
|
|
126
114
|
>>> SortParams.from_string("-created_at,priority")
|
|
127
|
-
SortParams(sorts=[('created_at', 'desc'), ('priority', '
|
|
115
|
+
SortParams(sorts=[('created_at', 'desc'), ('priority', 'asc')])
|
|
128
116
|
|
|
129
117
|
>>> SortParams.from_string("created_at:desc,priority:asc")
|
|
130
118
|
SortParams(sorts=[('created_at', 'desc'), ('priority', 'asc')])
|
|
@@ -233,66 +221,76 @@ class PaginationResult[ModelType](BaseModel):
|
|
|
233
221
|
"""分页结果。
|
|
234
222
|
|
|
235
223
|
封装分页查询的结果,包括数据列表和分页信息。
|
|
224
|
+
同时提供 offset/limit 和 page/size 两种风格的字段。
|
|
236
225
|
"""
|
|
237
226
|
|
|
238
227
|
items: list[ModelType] = Field(description="数据列表")
|
|
239
228
|
total: int = Field(ge=0, description="总记录数")
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
total_pages: int = Field(ge=0, description="总页数")
|
|
229
|
+
offset: int = Field(ge=0, description="当前偏移量")
|
|
230
|
+
limit: int = Field(ge=1, description="每页记录数")
|
|
243
231
|
has_next: bool = Field(description="是否有下一页")
|
|
244
232
|
has_prev: bool = Field(description="是否有上一页")
|
|
245
233
|
|
|
234
|
+
@property
|
|
235
|
+
def page(self) -> int:
|
|
236
|
+
"""当前页码(从 1 开始)。"""
|
|
237
|
+
if self.limit == 0:
|
|
238
|
+
return 1
|
|
239
|
+
return self.offset // self.limit + 1
|
|
240
|
+
|
|
241
|
+
@property
|
|
242
|
+
def size(self) -> int:
|
|
243
|
+
"""每页记录数(limit 的别名)。"""
|
|
244
|
+
return self.limit
|
|
245
|
+
|
|
246
|
+
@property
|
|
247
|
+
def total_pages(self) -> int:
|
|
248
|
+
"""总页数。"""
|
|
249
|
+
if self.limit == 0:
|
|
250
|
+
return 0
|
|
251
|
+
return (self.total + self.limit - 1) // self.limit
|
|
252
|
+
|
|
246
253
|
@classmethod
|
|
247
254
|
def create(
|
|
248
255
|
cls,
|
|
249
256
|
items: list[ModelType],
|
|
250
257
|
total: int,
|
|
251
|
-
|
|
252
|
-
) -> PaginationResult[ModelType]:
|
|
258
|
+
pagination: PaginationParams,
|
|
259
|
+
) -> "PaginationResult[ModelType]":
|
|
253
260
|
"""创建分页结果。
|
|
254
261
|
|
|
255
262
|
Args:
|
|
256
263
|
items: 数据列表
|
|
257
264
|
total: 总记录数
|
|
258
|
-
|
|
265
|
+
pagination: 分页参数
|
|
259
266
|
|
|
260
267
|
Returns:
|
|
261
268
|
PaginationResult[ModelType]: 分页结果
|
|
262
269
|
"""
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
has_prev = pagination_params.page > 1
|
|
270
|
+
has_next = pagination.offset + pagination.limit < total
|
|
271
|
+
has_prev = pagination.offset > 0
|
|
266
272
|
|
|
267
273
|
return cls(
|
|
268
274
|
items=items,
|
|
269
275
|
total=total,
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
total_pages=total_pages,
|
|
276
|
+
offset=pagination.offset,
|
|
277
|
+
limit=pagination.limit,
|
|
273
278
|
has_next=has_next,
|
|
274
279
|
has_prev=has_prev,
|
|
275
280
|
)
|
|
276
281
|
|
|
277
282
|
def get_next_params(self) -> PaginationParams | None:
|
|
278
|
-
"""获取下一页的分页参数。
|
|
279
|
-
|
|
280
|
-
Returns:
|
|
281
|
-
PaginationParams | None: 下一页的分页参数,如果没有下一页则返回None
|
|
282
|
-
"""
|
|
283
|
+
"""获取下一页的分页参数。"""
|
|
283
284
|
if not self.has_next:
|
|
284
285
|
return None
|
|
285
|
-
return PaginationParams(
|
|
286
|
+
return PaginationParams(offset=self.offset + self.limit, limit=self.limit)
|
|
286
287
|
|
|
287
288
|
def get_prev_params(self) -> PaginationParams | None:
|
|
288
|
-
"""获取上一页的分页参数。
|
|
289
|
-
|
|
290
|
-
Returns:
|
|
291
|
-
PaginationParams | None: 上一页的分页参数,如果没有上一页则返回None
|
|
292
|
-
"""
|
|
289
|
+
"""获取上一页的分页参数。"""
|
|
293
290
|
if not self.has_prev:
|
|
294
291
|
return None
|
|
295
|
-
|
|
292
|
+
new_offset = max(0, self.offset - self.limit)
|
|
293
|
+
return PaginationParams(offset=new_offset, limit=self.limit)
|
|
296
294
|
|
|
297
295
|
|
|
298
296
|
class CursorPaginationParams(BaseModel):
|
|
@@ -224,45 +224,113 @@ class BaseRepository[ModelType: Base](IRepository[ModelType]):
|
|
|
224
224
|
result = await self._session.execute(query)
|
|
225
225
|
return result.scalar_one_or_none()
|
|
226
226
|
|
|
227
|
-
async def list(
|
|
227
|
+
async def list(
|
|
228
|
+
self,
|
|
229
|
+
skip: int = 0,
|
|
230
|
+
limit: int | None = None,
|
|
231
|
+
sort: str | SortParams | list[str] | None = None,
|
|
232
|
+
**filters
|
|
233
|
+
) -> list[ModelType]:
|
|
234
|
+
"""获取实体列表。
|
|
235
|
+
|
|
236
|
+
Args:
|
|
237
|
+
skip: 跳过记录数
|
|
238
|
+
limit: 返回记录数限制,None 表示不限制(默认)
|
|
239
|
+
sort: 排序参数,支持多种格式:
|
|
240
|
+
- 字符串: "-created_at" 或 "created_at:desc" 或 "-created_at,name"
|
|
241
|
+
- SortParams 对象
|
|
242
|
+
- 字符串列表: ["-created_at", "name"]
|
|
243
|
+
**filters: 过滤条件
|
|
244
|
+
|
|
245
|
+
Returns:
|
|
246
|
+
list[ModelType]: 实体列表
|
|
247
|
+
"""
|
|
228
248
|
query = self._build_base_query()
|
|
229
249
|
query = self._apply_filters(query, **filters)
|
|
250
|
+
query = self._apply_sort(query, sort)
|
|
230
251
|
query = query.offset(skip)
|
|
231
252
|
if limit is not None:
|
|
232
253
|
query = query.limit(limit)
|
|
233
254
|
result = await self._session.execute(query)
|
|
234
255
|
return list(result.scalars().all())
|
|
235
256
|
|
|
257
|
+
def _apply_sort(
|
|
258
|
+
self,
|
|
259
|
+
query: Select,
|
|
260
|
+
sort: str | SortParams | list[str] | None,
|
|
261
|
+
) -> Select:
|
|
262
|
+
"""应用排序参数到查询。
|
|
263
|
+
|
|
264
|
+
Args:
|
|
265
|
+
query: SQLAlchemy 查询对象
|
|
266
|
+
sort: 排序参数,支持:
|
|
267
|
+
- 字符串: "-created_at" 或 "created_at:desc" 或 "-created_at,name"
|
|
268
|
+
- SortParams 对象
|
|
269
|
+
- 字符串列表: ["-created_at", "name"]
|
|
270
|
+
|
|
271
|
+
Returns:
|
|
272
|
+
Select: 应用排序后的查询对象
|
|
273
|
+
"""
|
|
274
|
+
if sort is None:
|
|
275
|
+
return query
|
|
276
|
+
|
|
277
|
+
# 统一转换为 SortParams
|
|
278
|
+
sort_params: SortParams
|
|
279
|
+
if isinstance(sort, SortParams):
|
|
280
|
+
sort_params = sort
|
|
281
|
+
elif isinstance(sort, str):
|
|
282
|
+
sort_params = SortParams.from_string(sort)
|
|
283
|
+
elif isinstance(sort, list):
|
|
284
|
+
# 列表格式: ["-created_at", "name"]
|
|
285
|
+
sort_params = SortParams.from_string(",".join(sort))
|
|
286
|
+
else:
|
|
287
|
+
return query
|
|
288
|
+
|
|
289
|
+
order_by_list = []
|
|
290
|
+
for field, direction in sort_params.sorts:
|
|
291
|
+
field_attr = getattr(self._model_class, field, None)
|
|
292
|
+
if field_attr is not None:
|
|
293
|
+
if direction == "desc":
|
|
294
|
+
order_by_list.append(field_attr.desc())
|
|
295
|
+
else:
|
|
296
|
+
order_by_list.append(field_attr)
|
|
297
|
+
|
|
298
|
+
if order_by_list:
|
|
299
|
+
query = query.order_by(*order_by_list)
|
|
300
|
+
|
|
301
|
+
return query
|
|
302
|
+
|
|
236
303
|
async def paginate(
|
|
237
304
|
self,
|
|
238
|
-
|
|
239
|
-
|
|
305
|
+
pagination: PaginationParams,
|
|
306
|
+
sort: str | SortParams | list[str] | None = None,
|
|
240
307
|
**filters
|
|
241
308
|
) -> PaginationResult[ModelType]:
|
|
242
|
-
|
|
243
|
-
query = self._apply_filters(query, **filters)
|
|
309
|
+
"""分页查询(list 的语法糖)。
|
|
244
310
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
311
|
+
Args:
|
|
312
|
+
pagination: 分页参数
|
|
313
|
+
sort: 排序参数,支持多种格式:
|
|
314
|
+
- 字符串: "-created_at" 或 "created_at:desc" 或 "-created_at,name"
|
|
315
|
+
- SortParams 对象
|
|
316
|
+
- 字符串列表: ["-created_at", "name"]
|
|
317
|
+
**filters: 过滤条件
|
|
318
|
+
|
|
319
|
+
Returns:
|
|
320
|
+
PaginationResult[ModelType]: 分页结果
|
|
321
|
+
"""
|
|
322
|
+
items = await self.list(
|
|
323
|
+
skip=pagination.offset,
|
|
324
|
+
limit=pagination.limit,
|
|
325
|
+
sort=sort,
|
|
326
|
+
**filters
|
|
327
|
+
)
|
|
328
|
+
total = await self.count(**filters)
|
|
261
329
|
|
|
262
330
|
return PaginationResult.create(
|
|
263
331
|
items=items,
|
|
264
|
-
total=
|
|
265
|
-
|
|
332
|
+
total=total,
|
|
333
|
+
pagination=pagination,
|
|
266
334
|
)
|
|
267
335
|
|
|
268
336
|
async def cursor_paginate(
|
|
@@ -374,6 +442,7 @@ class BaseRepository[ModelType: Base](IRepository[ModelType]):
|
|
|
374
442
|
async def stream(
|
|
375
443
|
self,
|
|
376
444
|
batch_size: int = 1000,
|
|
445
|
+
sort: str | SortParams | list[str] | None = None,
|
|
377
446
|
**filters
|
|
378
447
|
):
|
|
379
448
|
"""流式查询,使用数据库原生 server-side cursor。
|
|
@@ -382,17 +451,19 @@ class BaseRepository[ModelType: Base](IRepository[ModelType]):
|
|
|
382
451
|
|
|
383
452
|
Args:
|
|
384
453
|
batch_size: 每批次获取的记录数,默认 1000
|
|
454
|
+
sort: 排序参数(同 list)
|
|
385
455
|
**filters: 过滤条件
|
|
386
456
|
|
|
387
457
|
Yields:
|
|
388
458
|
ModelType: 模型实例
|
|
389
459
|
|
|
390
460
|
示例:
|
|
391
|
-
async for user in repo.stream(batch_size=500, status="active"):
|
|
461
|
+
async for user in repo.stream(batch_size=500, sort="-created_at", status="active"):
|
|
392
462
|
process(user)
|
|
393
463
|
"""
|
|
394
464
|
query = self._build_base_query()
|
|
395
465
|
query = self._apply_filters(query, **filters)
|
|
466
|
+
query = self._apply_sort(query, sort)
|
|
396
467
|
|
|
397
468
|
async with self._session.stream_scalars(
|
|
398
469
|
query.execution_options(yield_per=batch_size)
|
|
@@ -403,23 +474,26 @@ class BaseRepository[ModelType: Base](IRepository[ModelType]):
|
|
|
403
474
|
async def stream_batches(
|
|
404
475
|
self,
|
|
405
476
|
batch_size: int = 1000,
|
|
477
|
+
sort: str | SortParams | list[str] | None = None,
|
|
406
478
|
**filters
|
|
407
479
|
):
|
|
408
480
|
"""批量流式查询,每次返回一批数据。
|
|
409
481
|
|
|
410
482
|
Args:
|
|
411
483
|
batch_size: 每批次的记录数,默认 1000
|
|
484
|
+
sort: 排序参数(同 list)
|
|
412
485
|
**filters: 过滤条件
|
|
413
486
|
|
|
414
487
|
Yields:
|
|
415
488
|
list[ModelType]: 一批模型实例
|
|
416
489
|
|
|
417
490
|
示例:
|
|
418
|
-
async for batch in repo.stream_batches(batch_size=500):
|
|
491
|
+
async for batch in repo.stream_batches(batch_size=500, sort="id"):
|
|
419
492
|
bulk_process(batch)
|
|
420
493
|
"""
|
|
421
494
|
query = self._build_base_query()
|
|
422
495
|
query = self._apply_filters(query, **filters)
|
|
496
|
+
query = self._apply_sort(query, sort)
|
|
423
497
|
|
|
424
498
|
async with self._session.stream_scalars(
|
|
425
499
|
query.execution_options(yield_per=batch_size)
|
|
@@ -437,7 +511,10 @@ class BaseRepository[ModelType: Base](IRepository[ModelType]):
|
|
|
437
511
|
return result.scalar_one()
|
|
438
512
|
|
|
439
513
|
async def exists(self, **filters) -> bool:
|
|
440
|
-
|
|
514
|
+
"""检查是否存在匹配的记录(比 count > 0 更高效)。"""
|
|
515
|
+
query = self._apply_filters(self._build_base_query(), **filters).limit(1)
|
|
516
|
+
result = await self._session.execute(query)
|
|
517
|
+
return result.scalar_one_or_none() is not None
|
|
441
518
|
|
|
442
519
|
async def add(self, entity: ModelType) -> ModelType:
|
|
443
520
|
self._session.add(entity)
|
|
@@ -35,22 +35,41 @@ class IRepository[ModelType: Base](ABC):
|
|
|
35
35
|
pass
|
|
36
36
|
|
|
37
37
|
@abstractmethod
|
|
38
|
-
async def list(
|
|
39
|
-
|
|
38
|
+
async def list(
|
|
39
|
+
self,
|
|
40
|
+
skip: int = 0,
|
|
41
|
+
limit: int | None = None,
|
|
42
|
+
sort: str | SortParams | list[str] | None = None,
|
|
43
|
+
**filters
|
|
44
|
+
) -> list[ModelType]:
|
|
45
|
+
"""获取实体列表。
|
|
46
|
+
|
|
47
|
+
Args:
|
|
48
|
+
skip: 跳过记录数
|
|
49
|
+
limit: 返回记录数限制,None 表示不限制(默认)
|
|
50
|
+
sort: 排序参数,支持多种格式:
|
|
51
|
+
- 字符串: "-created_at" 或 "created_at:desc" 或 "-created_at,name"
|
|
52
|
+
- SortParams 对象
|
|
53
|
+
- 字符串列表: ["-created_at", "name"]
|
|
54
|
+
**filters: 过滤条件
|
|
55
|
+
|
|
56
|
+
Returns:
|
|
57
|
+
list[ModelType]: 实体列表
|
|
58
|
+
"""
|
|
40
59
|
pass
|
|
41
60
|
|
|
42
61
|
@abstractmethod
|
|
43
62
|
async def paginate(
|
|
44
63
|
self,
|
|
45
|
-
|
|
46
|
-
|
|
64
|
+
pagination: PaginationParams,
|
|
65
|
+
sort: str | SortParams | list[str] | None = None,
|
|
47
66
|
**filters
|
|
48
67
|
) -> PaginationResult[ModelType]:
|
|
49
|
-
"""
|
|
68
|
+
"""分页查询(list 的语法糖)。
|
|
50
69
|
|
|
51
70
|
Args:
|
|
52
|
-
|
|
53
|
-
|
|
71
|
+
pagination: 分页参数
|
|
72
|
+
sort: 排序参数,支持多种格式(同 list)
|
|
54
73
|
**filters: 过滤条件
|
|
55
74
|
|
|
56
75
|
Returns:
|
{aury_boot-0.0.32 → aury_boot-0.0.34}/aury/boot/infrastructure/monitoring/alerting/__init__.py
RENAMED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
from .aggregator import AlertAggregator
|
|
29
29
|
from .events import AlertEvent, AlertEventType, AlertNotification, AlertSeverity
|
|
30
|
-
from .manager import AlertManager, emit_alert
|
|
30
|
+
from .manager import AlertManager, emit_alert, emit_exception_alert
|
|
31
31
|
from .notifiers import AlertNotifier, FeishuNotifier, WebhookNotifier
|
|
32
32
|
from .rules import AlertRule, load_rules_from_dict
|
|
33
33
|
|
|
@@ -46,5 +46,6 @@ __all__ = [
|
|
|
46
46
|
"WebhookNotifier",
|
|
47
47
|
# 便捷函数
|
|
48
48
|
"emit_alert",
|
|
49
|
+
"emit_exception_alert",
|
|
49
50
|
"load_rules_from_dict",
|
|
50
51
|
]
|