tina4-python 3.13.124__tar.gz → 3.13.126__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.
- {tina4_python-3.13.124 → tina4_python-3.13.126}/PKG-INFO +1 -1
- {tina4_python-3.13.124 → tina4_python-3.13.126}/pyproject.toml +1 -1
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/__init__.py +1 -1
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/cli/__init__.py +4 -4
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/firebird.py +1 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/mssql.py +1 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/mysql.py +1 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/sql_translator.py +43 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/seeder/__init__.py +43 -8
- {tina4_python-3.13.124 → tina4_python-3.13.126}/.gitignore +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/README.md +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/CLAUDE.md +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/HtmlElement.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/Testing.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/_import_helper.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/ai/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/ai/client.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/api/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/auth/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/cache/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/container/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/context/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/context/chunker.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/cache.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/constants.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/events.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/middleware.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/port_takeover.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/rate_limiter.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/request.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/response.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/router.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/core/server.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/crud/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/adapter.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/connection.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/database_url.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/mongodb.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/odbc.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/postgres.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/database/sqlite.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/debug/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/debug/error_overlay.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/dev_admin/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/dev_admin/metrics.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/dev_admin/plan.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/dev_admin/project_index.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/docs.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/docstore/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/dotenv/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/env.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/frond/FROND.md +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/frond/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/frond/compiler.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/frond/engine.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/frond/parser.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/auth/meta.json +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/auth/src/routes/api/gallery_auth.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/database/meta.json +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/database/src/routes/api/gallery_db.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/error-overlay/meta.json +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/error-overlay/src/routes/api/gallery_crash.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/orm/meta.json +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/orm/src/orm/Product.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/orm/src/routes/api/gallery_products.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/queue/meta.json +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/queue/src/routes/api/gallery_queue.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/rest-api/meta.json +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/rest-api/src/routes/api/gallery_hello.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/templates/meta.json +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/templates/src/routes/gallery_page.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/templates/src/templates/gallery_page.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/graph/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/graph/adapter.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/graph/adapters/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/graph/adapters/arango.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/graph/adapters/bolt.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/graph/adapters/ultipa.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/graph/graph_url.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/graphql/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/i18n/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/mcp/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/mcp/protocol.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/mcp/tools.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/messenger/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/migration/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/migration/runner.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/mqtt/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/mqtt/message.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/orm/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/orm/fields.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/orm/model.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/orm/point.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/__feedback/widget.js +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/css/tina4.css +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/css/tina4.min.css +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/favicon.ico +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/images/logo.svg +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/images/tina4-logo-icon.webp +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/js/frond.js +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/js/frond.min.js +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/js/tina4-dev-admin.min.js +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/js/tina4.min.js +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/js/tina4js.min.js +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/swagger/index.html +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/swagger/oauth2-redirect.html +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/query_builder/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue/amqp_url.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue/job.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue/kafka_backend.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue/lite_backend.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue/mongo_backend.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue/rabbitmq_backend.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue_backends/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue_backends/kafka_backend.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue_backends/mongo_backend.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue_backends/rabbitmq_backend.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/realtime/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/realtime/models/Attachment.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/realtime/models/Channel.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/realtime/models/ChannelMember.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/realtime/models/Message.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/realtime/models/Workspace.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/realtime/models/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/realtime/storage.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/service/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session_handlers/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session_handlers/memcached_handler.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session_handlers/mongodb_handler.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session_handlers/redis_handler.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session_handlers/valkey_handler.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/sso.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/swagger/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/components/crud.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/docker/distroless/Dockerfile +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/docker/poetry/Dockerfile +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/docker/python/Dockerfile +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/docker/uv/Dockerfile +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/errors/302.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/errors/401.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/errors/403.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/errors/404.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/errors/500.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/errors/502.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/errors/503.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/errors/base.twig +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/frontend/README.md +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/readme.md +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/test/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/test_client/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/af/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/af/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/en/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/en/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/es/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/es/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/fr/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/fr/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/ja/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/ja/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/zh/LC_MESSAGES/messages.mo +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/zh/LC_MESSAGES/messages.po +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/validator/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/websocket/__init__.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/websocket/backplane.py +0 -0
- {tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/wsdl/__init__.py +0 -0
|
@@ -31,8 +31,8 @@ from pathlib import Path
|
|
|
31
31
|
|
|
32
32
|
# ── Field type mapping ────────────────────────────────────────────────
|
|
33
33
|
FIELD_TYPE_MAP = {
|
|
34
|
-
"string": {"orm": "StringField", "sql": "
|
|
35
|
-
"str": {"orm": "StringField", "sql": "
|
|
34
|
+
"string": {"orm": "StringField", "sql": "VARCHAR(255)", "default": "''"},
|
|
35
|
+
"str": {"orm": "StringField", "sql": "VARCHAR(255)", "default": "''"},
|
|
36
36
|
"int": {"orm": "IntegerField", "sql": "INTEGER", "default": "0"},
|
|
37
37
|
"integer": {"orm": "IntegerField", "sql": "INTEGER", "default": "0"},
|
|
38
38
|
"float": {"orm": "NumericField", "sql": "REAL", "default": "0"},
|
|
@@ -41,7 +41,7 @@ FIELD_TYPE_MAP = {
|
|
|
41
41
|
"bool": {"orm": "BooleanField", "sql": "INTEGER", "default": "0"},
|
|
42
42
|
"boolean": {"orm": "BooleanField", "sql": "INTEGER", "default": "0"},
|
|
43
43
|
"text": {"orm": "TextField", "sql": "TEXT", "default": "''"},
|
|
44
|
-
"datetime": {"orm": "DateTimeField", "sql": "
|
|
44
|
+
"datetime": {"orm": "DateTimeField", "sql": "TIMESTAMP", "default": "NULL"},
|
|
45
45
|
"blob": {"orm": "BlobField", "sql": "BLOB", "default": "NULL"},
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -1941,7 +1941,7 @@ def _gen_migration(name: str, flags: dict = None, *,
|
|
|
1941
1941
|
info = FIELD_TYPE_MAP.get(ftype, FIELD_TYPE_MAP["string"])
|
|
1942
1942
|
default = f" DEFAULT {info['default']}" if info["default"] != "NULL" else ""
|
|
1943
1943
|
col_lines.append(f" {fname} {info['sql']}{default}")
|
|
1944
|
-
col_lines.append(" created_at
|
|
1944
|
+
col_lines.append(" created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP")
|
|
1945
1945
|
|
|
1946
1946
|
# ADR-0063: `tina4:edit` marker between the last column and the closing
|
|
1947
1947
|
# paren, placed OUTSIDE the comma-joined column list so the SQL stays
|
|
@@ -646,6 +646,7 @@ class FirebirdAdapter(SqlCrudMixin, DatabaseAdapter):
|
|
|
646
646
|
sql = SQLTranslator.ilike_to_like(sql)
|
|
647
647
|
sql = SQLTranslator.boolean_to_int(sql)
|
|
648
648
|
sql = SQLTranslator.auto_increment_syntax(sql, "firebird")
|
|
649
|
+
sql = SQLTranslator.ddl_types(sql, "firebird")
|
|
649
650
|
return sql
|
|
650
651
|
|
|
651
652
|
def _supports_returning(self) -> bool:
|
|
@@ -350,6 +350,7 @@ class MSSQLAdapter(SqlCrudMixin, DatabaseAdapter):
|
|
|
350
350
|
sql = SQLTranslator.ilike_to_like(sql)
|
|
351
351
|
sql = SQLTranslator.auto_increment_syntax(sql, "mssql")
|
|
352
352
|
sql = SQLTranslator.boolean_to_int(sql)
|
|
353
|
+
sql = SQLTranslator.ddl_types(sql, "mssql")
|
|
353
354
|
return sql
|
|
354
355
|
|
|
355
356
|
def _supports_returning(self) -> bool:
|
|
@@ -321,6 +321,7 @@ class MySQLAdapter(SqlCrudMixin, DatabaseAdapter):
|
|
|
321
321
|
sql = SQLTranslator.concat_pipes_to_func(sql)
|
|
322
322
|
sql = SQLTranslator.ilike_to_like(sql)
|
|
323
323
|
sql = SQLTranslator.auto_increment_syntax(sql, "mysql")
|
|
324
|
+
sql = SQLTranslator.ddl_types(sql, "mysql")
|
|
324
325
|
return sql
|
|
325
326
|
|
|
326
327
|
def _supports_returning(self) -> bool:
|
|
@@ -347,6 +347,49 @@ class SQLTranslator:
|
|
|
347
347
|
return re.sub(r"\s*AUTOINCREMENT\b", "", sql, flags=re.IGNORECASE)
|
|
348
348
|
return sql
|
|
349
349
|
|
|
350
|
+
@staticmethod
|
|
351
|
+
def ddl_types(sql: str, engine: str) -> str:
|
|
352
|
+
"""Translate SQLite-canonical DDL column TYPES + CREATE-TABLE options to
|
|
353
|
+
the target engine.
|
|
354
|
+
|
|
355
|
+
ONLY acts on ``CREATE TABLE`` / ``ALTER TABLE`` statements, so a query or
|
|
356
|
+
INSERT that happens to contain the word ``TEXT`` (a column name, a string
|
|
357
|
+
literal) is never rewritten. Complements ``auto_increment_syntax`` (which
|
|
358
|
+
maps the id keyword) so ONE portable migration — and every
|
|
359
|
+
``ORM.create_table()`` DDL, which is also SQLite-canonical — applies on
|
|
360
|
+
every engine instead of failing on Firebird/MSSQL.
|
|
361
|
+
|
|
362
|
+
* Firebird has no ``TEXT`` (-607), no ``REAL``, and no
|
|
363
|
+
``CREATE TABLE IF NOT EXISTS``.
|
|
364
|
+
* MSSQL has no ``CREATE TABLE IF NOT EXISTS`` and its ``TIMESTAMP`` is a
|
|
365
|
+
rowversion, not a datetime — a ``created_at TIMESTAMP`` there is wrong.
|
|
366
|
+
* MySQL's ``TIMESTAMP`` carries auto-update / 2038 surprises, so a
|
|
367
|
+
datetime column maps to ``DATETIME`` (matching ORM.create_table()).
|
|
368
|
+
"""
|
|
369
|
+
# Gate to DDL only, tolerating leading `-- ...` comment lines / blank
|
|
370
|
+
# lines that a migration file carries before its CREATE TABLE. A SELECT
|
|
371
|
+
# or INSERT that merely mentions a type keyword is never rewritten.
|
|
372
|
+
head = re.sub(r"^(?:\s*--[^\n]*\n)+", "", sql)
|
|
373
|
+
if not re.match(r"\s*(CREATE\s+TABLE|ALTER\s+TABLE)\b", head, re.IGNORECASE):
|
|
374
|
+
return sql
|
|
375
|
+
e = (engine or "").lower()
|
|
376
|
+
if e == "firebird":
|
|
377
|
+
sql = re.sub(r"\bIF\s+NOT\s+EXISTS\b", "", sql, flags=re.IGNORECASE)
|
|
378
|
+
# Map bare TEXT -> BLOB SUB_TYPE TEXT, but leave an existing
|
|
379
|
+
# "BLOB SUB_TYPE TEXT" intact (it already contains the word TEXT).
|
|
380
|
+
sql = re.sub(
|
|
381
|
+
r"\bBLOB\s+SUB_TYPE\s+TEXT\b", "\x00FBTEXT\x00", sql, flags=re.IGNORECASE
|
|
382
|
+
)
|
|
383
|
+
sql = re.sub(r"\bTEXT\b", "BLOB SUB_TYPE TEXT", sql, flags=re.IGNORECASE)
|
|
384
|
+
sql = sql.replace("\x00FBTEXT\x00", "BLOB SUB_TYPE TEXT")
|
|
385
|
+
sql = re.sub(r"\bREAL\b", "DOUBLE PRECISION", sql, flags=re.IGNORECASE)
|
|
386
|
+
elif e == "mssql":
|
|
387
|
+
sql = re.sub(r"\bIF\s+NOT\s+EXISTS\b", "", sql, flags=re.IGNORECASE)
|
|
388
|
+
sql = re.sub(r"\bTIMESTAMP\b", "DATETIME2", sql, flags=re.IGNORECASE)
|
|
389
|
+
elif e == "mysql":
|
|
390
|
+
sql = re.sub(r"\bTIMESTAMP\b", "DATETIME", sql, flags=re.IGNORECASE)
|
|
391
|
+
return sql
|
|
392
|
+
|
|
350
393
|
@staticmethod
|
|
351
394
|
def placeholder_style(sql: str, style: str = "?") -> str:
|
|
352
395
|
"""Convert ? placeholders to engine-specific style.
|
|
@@ -66,6 +66,35 @@ _JOB_TITLES = [
|
|
|
66
66
|
]
|
|
67
67
|
_CURRENCIES = ["USD", "EUR", "GBP", "JPY", "CAD", "AUD", "CHF", "ZAR", "INR", "CNY"]
|
|
68
68
|
_CREDIT_CARD_PREFIXES = ["4111", "4242", "5500", "5105"]
|
|
69
|
+
# Product-name vocabulary (adjective + noun). Seeds a `name` column on a
|
|
70
|
+
# product-ish table with "Wireless Keyboard" instead of a person name.
|
|
71
|
+
_PRODUCT_ADJECTIVES = [
|
|
72
|
+
"Wireless", "Organic", "Premium", "Classic", "Eco", "Smart", "Portable",
|
|
73
|
+
"Deluxe", "Compact", "Rustic", "Handcrafted", "Vintage", "Modern",
|
|
74
|
+
"Ergonomic", "Stainless", "Bamboo", "Recycled", "Artisan", "Professional",
|
|
75
|
+
"Ultra", "Insulated", "Lightweight", "Adjustable", "Foldable",
|
|
76
|
+
]
|
|
77
|
+
_PRODUCT_NOUNS = [
|
|
78
|
+
"Keyboard", "Coffee Beans", "Backpack", "Water Bottle", "Desk Lamp",
|
|
79
|
+
"Headphones", "Notebook", "Sneakers", "Sunglasses", "Wallet", "Mug",
|
|
80
|
+
"Chair", "Blender", "Speaker", "Charger", "Umbrella", "Toothbrush",
|
|
81
|
+
"Jacket", "Watch", "Kettle", "Picture Frame", "Planter", "Cutlery Set",
|
|
82
|
+
"Yoga Mat", "Phone Case",
|
|
83
|
+
]
|
|
84
|
+
# A table/model whose name contains any of these gets product names on its
|
|
85
|
+
# generic `name`/`full_name` column instead of a person name.
|
|
86
|
+
_PRODUCT_TABLE_HINTS = (
|
|
87
|
+
"product", "item", "catalog", "inventory", "goods", "merchandise",
|
|
88
|
+
"sku", "listing", "stock", "ware",
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def _is_product_table(table: str) -> bool:
|
|
93
|
+
"""True when the table/model name looks like a product catalogue, so a
|
|
94
|
+
generic ``name`` column should seed a product name, not a person name.
|
|
95
|
+
With no table context this is False, so the person-name default is kept
|
|
96
|
+
(back-compat)."""
|
|
97
|
+
return any(hint in (table or "").lower() for hint in _PRODUCT_TABLE_HINTS)
|
|
69
98
|
|
|
70
99
|
|
|
71
100
|
class FakeData:
|
|
@@ -227,7 +256,7 @@ class FakeData:
|
|
|
227
256
|
d = start + timedelta(seconds=self._rng.randint(0, delta))
|
|
228
257
|
return d.strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
229
258
|
|
|
230
|
-
def for_field(self, field_def: dict, column_name: str = None):
|
|
259
|
+
def for_field(self, field_def: dict, column_name: str = None, table: str = None):
|
|
231
260
|
"""Generate a fake value from a field definition dict and optional column name.
|
|
232
261
|
|
|
233
262
|
Args:
|
|
@@ -249,7 +278,7 @@ class FakeData:
|
|
|
249
278
|
if "phone" in col or "tel" in col or "mobile" in col:
|
|
250
279
|
return self.phone()
|
|
251
280
|
if col in ("full_name", "fullname", "name"):
|
|
252
|
-
return self.name()
|
|
281
|
+
return self.product() if _is_product_table(table) else self.name()
|
|
253
282
|
if "first_name" in col or ("first" in col and "name" in col):
|
|
254
283
|
return self.first_name()
|
|
255
284
|
if "last_name" in col or ("last" in col and "name" in col):
|
|
@@ -297,6 +326,11 @@ class FakeData:
|
|
|
297
326
|
def job_title(self) -> str:
|
|
298
327
|
return self._rng.choice(_JOB_TITLES)
|
|
299
328
|
|
|
329
|
+
def product(self) -> str:
|
|
330
|
+
"""A plausible product name, e.g. "Wireless Keyboard" or "Organic Coffee
|
|
331
|
+
Beans". Deterministic under a seed like every other generator."""
|
|
332
|
+
return f"{self._rng.choice(_PRODUCT_ADJECTIVES)} {self._rng.choice(_PRODUCT_NOUNS)}"
|
|
333
|
+
|
|
300
334
|
def currency(self) -> str:
|
|
301
335
|
return self._rng.choice(_CURRENCIES)
|
|
302
336
|
|
|
@@ -362,7 +396,7 @@ class SeedSummary(int):
|
|
|
362
396
|
return f"SeedSummary(seeded={self.seeded}, failed={self.failed}, errors={self.errors!r})"
|
|
363
397
|
|
|
364
398
|
|
|
365
|
-
def _generator_for_column(fake: "FakeData", name: str, col_type: str):
|
|
399
|
+
def _generator_for_column(fake: "FakeData", name: str, col_type: str, table: str = None):
|
|
366
400
|
"""Pick a FakeData generator for one column from its name + type.
|
|
367
401
|
|
|
368
402
|
The shared heuristic behind :func:`auto_field_map`, so the dev-admin
|
|
@@ -380,7 +414,7 @@ def _generator_for_column(fake: "FakeData", name: str, col_type: str):
|
|
|
380
414
|
if "last" in name_lower and "name" in name_lower:
|
|
381
415
|
return fake.last_name
|
|
382
416
|
if "name" in name_lower:
|
|
383
|
-
return fake.name
|
|
417
|
+
return fake.product if _is_product_table(table) else fake.name
|
|
384
418
|
if "phone" in name_lower or "tel" in name_lower:
|
|
385
419
|
return fake.phone
|
|
386
420
|
if "url" in name_lower or "link" in name_lower:
|
|
@@ -424,7 +458,7 @@ def auto_field_map(db, table: str, fake: "FakeData" = None) -> dict:
|
|
|
424
458
|
is_pk = col.get("primary_key", col.get("pk", False))
|
|
425
459
|
if is_pk and ("AUTO" in col_type or "SERIAL" in col_type or name.lower() == "id"):
|
|
426
460
|
continue
|
|
427
|
-
field_map[name] = _generator_for_column(fake, name, col_type)
|
|
461
|
+
field_map[name] = _generator_for_column(fake, name, col_type, table)
|
|
428
462
|
return field_map
|
|
429
463
|
|
|
430
464
|
|
|
@@ -584,7 +618,8 @@ def seed_orm(orm_class, count: int = 10,
|
|
|
584
618
|
elif name in fk_pools and fk_pools[name]:
|
|
585
619
|
attrs[name] = fake.choice(fk_pools[name])
|
|
586
620
|
else:
|
|
587
|
-
attrs[name] = _generate_for_field(fake, _field_meta(field), name
|
|
621
|
+
attrs[name] = _generate_for_field(fake, _field_meta(field), name,
|
|
622
|
+
table=orm_class.__name__)
|
|
588
623
|
_validate_types(fields, attrs, orm_class.__name__, Log)
|
|
589
624
|
obj = orm_class(attrs)
|
|
590
625
|
if obj.save():
|
|
@@ -813,7 +848,7 @@ def _topo_sort_models(orm_classes: list) -> list:
|
|
|
813
848
|
return ordered
|
|
814
849
|
|
|
815
850
|
|
|
816
|
-
def _generate_for_field(fake: FakeData, field_def: dict, col: str):
|
|
851
|
+
def _generate_for_field(fake: FakeData, field_def: dict, col: str, table: str = None):
|
|
817
852
|
"""Generate a fake value for an ORM field definition + column name."""
|
|
818
853
|
col = col.lower()
|
|
819
854
|
ftype = field_def.get("type", "string")
|
|
@@ -842,7 +877,7 @@ def _generate_for_field(fake: FakeData, field_def: dict, col: str):
|
|
|
842
877
|
if "email" in col:
|
|
843
878
|
return fake.email()
|
|
844
879
|
if col in ("name", "full_name", "fullname"):
|
|
845
|
-
return fake.name()
|
|
880
|
+
return fake.product() if _is_product_table(table) else fake.name()
|
|
846
881
|
if "first" in col and "name" in col:
|
|
847
882
|
return fake.first_name()
|
|
848
883
|
if "last" in col and "name" in col:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/gallery/error-overlay/meta.json
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/images/tina4-logo-icon.webp
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/js/tina4-dev-admin.min.js
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/public/swagger/oauth2-redirect.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue_backends/kafka_backend.py
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue_backends/mongo_backend.py
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/queue_backends/rabbitmq_backend.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/realtime/models/ChannelMember.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session_handlers/memcached_handler.py
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session_handlers/mongodb_handler.py
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session_handlers/redis_handler.py
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/session_handlers/valkey_handler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/docker/distroless/Dockerfile
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/docker/poetry/Dockerfile
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/templates/docker/python/Dockerfile
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/af/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/af/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/en/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/en/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/es/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/es/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/fr/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/fr/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/ja/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/ja/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/zh/LC_MESSAGES/messages.mo
RENAMED
|
File without changes
|
{tina4_python-3.13.124 → tina4_python-3.13.126}/tina4_python/translations/zh/LC_MESSAGES/messages.po
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|