piccolo 1.10.0__tar.gz → 1.11.0__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.
- {piccolo-1.10.0 → piccolo-1.11.0}/PKG-INFO +1 -1
- piccolo-1.11.0/piccolo/__init__.py +1 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/column_types.py +28 -35
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/functions/__init__.py +11 -1
- piccolo-1.11.0/piccolo/query/functions/datetime.py +260 -0
- piccolo-1.11.0/piccolo/query/functions/string.py +118 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo.egg-info/PKG-INFO +1 -1
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo.egg-info/SOURCES.txt +2 -0
- piccolo-1.11.0/tests/query/functions/test_datetime.py +114 -0
- piccolo-1.11.0/tests/query/functions/test_string.py +57 -0
- piccolo-1.10.0/piccolo/__init__.py +0 -1
- piccolo-1.10.0/piccolo/query/functions/string.py +0 -73
- piccolo-1.10.0/tests/query/functions/test_string.py +0 -25
- {piccolo-1.10.0 → piccolo-1.11.0}/LICENSE +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/README.md +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/app/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/app/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/app/commands/new.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/app/commands/show_all.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/app/commands/templates/piccolo_app.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/app/commands/templates/tables.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/app/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/new.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/README.md.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/_blacksheep_app.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/_esmerald_app.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/_fastapi_app.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/_lilya_app.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/_litestar_app.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/_starlette_app.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/app.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/conftest.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/__init__.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/_blacksheep_endpoints.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/_esmerald_endpoints.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/_lilya_endpoints.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/_litestar_endpoints.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/_starlette_endpoints.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_app.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_migrations/README.md +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/tables.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/templates/base.html.jinja_raw +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/main.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf_test.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/requirements.txt.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/static/favicon.ico +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/commands/templates/app/static/main.css +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/asgi/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/fixtures/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/fixtures/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/fixtures/commands/dump.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/fixtures/commands/load.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/fixtures/commands/shared.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/fixtures/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/meta/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/meta/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/meta/commands/version.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/meta/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/auto/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/auto/diffable_table.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/auto/migration_manager.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/auto/operations.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/auto/schema_differ.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/auto/schema_snapshot.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/auto/serialisation.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/auto/serialisation_legacy.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/commands/backwards.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/commands/base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/commands/check.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/commands/clean.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/commands/forwards.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/commands/new.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/commands/templates/migration.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/migrations/tables.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/playground/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/playground/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/playground/commands/run.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/playground/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/project/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/project/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/project/commands/new.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/project/commands/templates/piccolo_conf.py.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/project/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/schema/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/schema/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/schema/commands/exceptions.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/schema/commands/generate.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/schema/commands/graph.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/schema/commands/templates/graphviz.dot.jinja +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/schema/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/shell/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/shell/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/shell/commands/run.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/shell/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/sql_shell/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/sql_shell/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/sql_shell/commands/run.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/sql_shell/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/tester/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/tester/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/tester/commands/run.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/tester/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/commands/change_password.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/commands/change_permissions.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/commands/create.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/commands/list.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/piccolo_migrations/2019-11-14T21-52-21.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/piccolo_migrations/2020-06-11T21-38-55.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/piccolo_migrations/2021-04-30T16-14-15.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/piccolo_migrations/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/apps/user/tables.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/choices.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/combination.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/defaults/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/defaults/base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/defaults/date.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/defaults/interval.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/defaults/time.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/defaults/timestamp.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/defaults/timestamptz.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/defaults/uuid.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/indexes.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/m2m.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/operators/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/operators/base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/operators/comparison.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/operators/math.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/operators/string.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/readable.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/columns/reference.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/conf/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/conf/apps.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/custom_types.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/engine/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/engine/base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/engine/cockroach.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/engine/exceptions.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/engine/finder.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/engine/postgres.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/engine/sqlite.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/main.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/py.typed +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/functions/aggregate.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/functions/base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/functions/math.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/functions/type_conversion.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/alter.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/count.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/create.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/create_index.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/delete.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/drop_index.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/exists.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/indexes.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/insert.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/objects.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/raw.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/refresh.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/select.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/table_exists.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/methods/update.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/mixins.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/query/proxy.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/querystring.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/schema.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/table.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/table_reflection.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/testing/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/testing/model_builder.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/testing/random_builder.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/dictionary.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/encoding.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/graphlib/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/graphlib/_graphlib.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/lazy_loader.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/list.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/naming.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/objects.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/printing.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/pydantic.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/repr.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/sql_values.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/sync.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo/utils/warnings.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo.egg-info/dependency_links.txt +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo.egg-info/entry_points.txt +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo.egg-info/requires.txt +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/piccolo.egg-info/top_level.txt +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/profiling/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/profiling/run_profile.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/pyproject.toml +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/setup.cfg +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/setup.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/app/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/app/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/app/commands/test_new.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/app/commands/test_show_all.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/asgi/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/asgi/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/asgi/commands/test_new.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/fixtures/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/fixtures/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/fixtures/commands/test_dump_load.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/fixtures/commands/test_shared.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/meta/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/meta/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/meta/commands/test_version.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/auto/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/auto/integration/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/auto/integration/test_migrations.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/auto/test_diffable_table.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/auto/test_migration_manager.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/auto/test_schema_differ.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/auto/test_schema_snapshot.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/auto/test_serialisation.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/commands/test_base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/commands/test_check.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/commands/test_clean.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/commands/test_forwards_backwards.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/commands/test_migrations/2020-03-31T20-38-22.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/commands/test_migrations/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/commands/test_new.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/migrations/test_migration.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/project/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/project/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/project/commands/test_new.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/schema/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/shell/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/shell/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/shell/commands/test_run.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/sql_shell/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/sql_shell/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/sql_shell/commands/test_run.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/tester/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/user/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/user/commands/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/user/commands/test_change_password.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/user/commands/test_change_permissions.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/user/commands/test_create.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/user/commands/test_list.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/apps/user/test_tables.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/m2m/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/m2m/base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/m2m/test_m2m.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/m2m/test_m2m_schema.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_array.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_bigint.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_boolean.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_bytea.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_choices.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_combination.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_date.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_db_column_name.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_defaults.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_double_precision.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_get_sql_value.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_interval.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_json.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_jsonb.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_numeric.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_primary_key.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_readable.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_real.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_reference.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_reserved_column_names.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_smallint.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_time.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_timestamp.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_timestamptz.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_uuid.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/columns/test_varchar.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/conf/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/conf/example.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/conf/test_apps.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/engine/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/engine/test_extra_nodes.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/engine/test_logging.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/engine/test_nested_transaction.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/engine/test_pool.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/engine/test_transaction.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/engine/test_version_parsing.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/mega/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/mega/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/mega/piccolo_migrations/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/mega/tables.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/music/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/music/piccolo_app.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/music/tables.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/example_apps/music/tables_detailed.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/functions/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/functions/base.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/functions/test_functions.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/functions/test_math.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/functions/test_type_conversion.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/mixins/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/mixins/test_columns_delegate.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/mixins/test_order_by_delegate.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/test_await.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/test_camelcase.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/test_freeze.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/test_gather.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/test_querystring.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/query/test_slots.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/instance/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/instance/test_create.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/instance/test_get_related.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/instance/test_get_related_readable.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/instance/test_instantiate.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/instance/test_remove.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/instance/test_save.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/instance/test_to_dict.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_all_columns.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_alter.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_batch.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_callback.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_constructor.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_count.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_create.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_create_db_tables.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_create_table_class.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_delete.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_drop_db_tables.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_exists.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_from_dict.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_indexes.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_inheritance.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_insert.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_join.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_join_on.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_metaclass.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_objects.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_output.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_raw.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_ref.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_refresh.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_repr.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_select.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_str.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_table_exists.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/table/test_update.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/test_main.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/test_schema.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/testing/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/testing/test_model_builder.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/testing/test_random_builder.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/__init__.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_dictionary.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_encoding.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_lazy_loader.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_list.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_naming.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_printing.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_pydantic.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_sql_values.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_sync.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_table_reflection.py +0 -0
- {piccolo-1.10.0 → piccolo-1.11.0}/tests/utils/test_warnings.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "1.11.0"
|
@@ -86,47 +86,38 @@ class ConcatDelegate:
|
|
86
86
|
|
87
87
|
def get_querystring(
|
88
88
|
self,
|
89
|
-
|
90
|
-
value: t.Union[str,
|
89
|
+
column: Column,
|
90
|
+
value: t.Union[str, Column, QueryString],
|
91
91
|
reverse: bool = False,
|
92
92
|
) -> QueryString:
|
93
|
-
|
94
|
-
|
93
|
+
"""
|
94
|
+
:param reverse:
|
95
|
+
By default the value is appended to the column's value. If
|
96
|
+
``reverse=True`` then the value is prepended to the column's
|
97
|
+
value instead.
|
98
|
+
|
99
|
+
"""
|
100
|
+
if isinstance(value, Column):
|
95
101
|
if len(column._meta.call_chain) > 0:
|
96
102
|
raise ValueError(
|
97
103
|
"Adding values across joins isn't currently supported."
|
98
104
|
)
|
99
|
-
other_column_name = column._meta.db_column_name
|
100
|
-
if reverse:
|
101
|
-
return QueryString(
|
102
|
-
Concat.template.format(
|
103
|
-
value_1=other_column_name, value_2=column_name
|
104
|
-
)
|
105
|
-
)
|
106
|
-
else:
|
107
|
-
return QueryString(
|
108
|
-
Concat.template.format(
|
109
|
-
value_1=column_name, value_2=other_column_name
|
110
|
-
)
|
111
|
-
)
|
112
105
|
elif isinstance(value, str):
|
113
|
-
|
114
|
-
|
115
|
-
return QueryString(
|
116
|
-
Concat.template.format(value_1="{}", value_2=column_name),
|
117
|
-
value_1,
|
118
|
-
)
|
119
|
-
else:
|
120
|
-
value_2 = QueryString("CAST({} AS text)", value)
|
121
|
-
return QueryString(
|
122
|
-
Concat.template.format(value_1=column_name, value_2="{}"),
|
123
|
-
value_2,
|
124
|
-
)
|
125
|
-
else:
|
106
|
+
value = QueryString("CAST({} AS TEXT)", value)
|
107
|
+
elif not isinstance(value, QueryString):
|
126
108
|
raise ValueError(
|
127
|
-
"Only str,
|
109
|
+
"Only str, Column and QueryString values can be added."
|
128
110
|
)
|
129
111
|
|
112
|
+
args = [value, column] if reverse else [column, value]
|
113
|
+
|
114
|
+
# We use the concat operator instead of the concat function, because
|
115
|
+
# this is what we historically used, and they treat null values
|
116
|
+
# differently.
|
117
|
+
return QueryString(
|
118
|
+
Concat.template.format(value_1="{}", value_2="{}"), *args
|
119
|
+
)
|
120
|
+
|
130
121
|
|
131
122
|
class MathDelegate:
|
132
123
|
"""
|
@@ -340,12 +331,13 @@ class Varchar(Column):
|
|
340
331
|
|
341
332
|
def __add__(self, value: t.Union[str, Varchar, Text]) -> QueryString:
|
342
333
|
return self.concat_delegate.get_querystring(
|
343
|
-
|
334
|
+
column=self,
|
335
|
+
value=value,
|
344
336
|
)
|
345
337
|
|
346
338
|
def __radd__(self, value: t.Union[str, Varchar, Text]) -> QueryString:
|
347
339
|
return self.concat_delegate.get_querystring(
|
348
|
-
|
340
|
+
column=self,
|
349
341
|
value=value,
|
350
342
|
reverse=True,
|
351
343
|
)
|
@@ -442,12 +434,13 @@ class Text(Column):
|
|
442
434
|
|
443
435
|
def __add__(self, value: t.Union[str, Varchar, Text]) -> QueryString:
|
444
436
|
return self.concat_delegate.get_querystring(
|
445
|
-
|
437
|
+
column=self,
|
438
|
+
value=value,
|
446
439
|
)
|
447
440
|
|
448
441
|
def __radd__(self, value: t.Union[str, Varchar, Text]) -> QueryString:
|
449
442
|
return self.concat_delegate.get_querystring(
|
450
|
-
|
443
|
+
column=self,
|
451
444
|
value=value,
|
452
445
|
reverse=True,
|
453
446
|
)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from .aggregate import Avg, Count, Max, Min, Sum
|
2
|
+
from .datetime import Day, Extract, Hour, Month, Second, Strftime, Year
|
2
3
|
from .math import Abs, Ceil, Floor, Round
|
3
|
-
from .string import Length, Lower, Ltrim, Reverse, Rtrim, Upper
|
4
|
+
from .string import Concat, Length, Lower, Ltrim, Reverse, Rtrim, Upper
|
4
5
|
from .type_conversion import Cast
|
5
6
|
|
6
7
|
__all__ = (
|
@@ -8,16 +9,25 @@ __all__ = (
|
|
8
9
|
"Avg",
|
9
10
|
"Cast",
|
10
11
|
"Ceil",
|
12
|
+
"Concat",
|
11
13
|
"Count",
|
14
|
+
"Day",
|
15
|
+
"Extract",
|
16
|
+
"Extract",
|
12
17
|
"Floor",
|
18
|
+
"Hour",
|
13
19
|
"Length",
|
14
20
|
"Lower",
|
15
21
|
"Ltrim",
|
16
22
|
"Max",
|
17
23
|
"Min",
|
24
|
+
"Month",
|
18
25
|
"Reverse",
|
19
26
|
"Round",
|
20
27
|
"Rtrim",
|
28
|
+
"Second",
|
29
|
+
"Strftime",
|
21
30
|
"Sum",
|
22
31
|
"Upper",
|
32
|
+
"Year",
|
23
33
|
)
|
@@ -0,0 +1,260 @@
|
|
1
|
+
import typing as t
|
2
|
+
|
3
|
+
from piccolo.columns.base import Column
|
4
|
+
from piccolo.columns.column_types import (
|
5
|
+
Date,
|
6
|
+
Integer,
|
7
|
+
Time,
|
8
|
+
Timestamp,
|
9
|
+
Timestamptz,
|
10
|
+
)
|
11
|
+
from piccolo.querystring import QueryString
|
12
|
+
|
13
|
+
from .type_conversion import Cast
|
14
|
+
|
15
|
+
###############################################################################
|
16
|
+
# Postgres / Cockroach
|
17
|
+
|
18
|
+
ExtractComponent = t.Literal[
|
19
|
+
"century",
|
20
|
+
"day",
|
21
|
+
"decade",
|
22
|
+
"dow",
|
23
|
+
"doy",
|
24
|
+
"epoch",
|
25
|
+
"hour",
|
26
|
+
"isodow",
|
27
|
+
"isoyear",
|
28
|
+
"julian",
|
29
|
+
"microseconds",
|
30
|
+
"millennium",
|
31
|
+
"milliseconds",
|
32
|
+
"minute",
|
33
|
+
"month",
|
34
|
+
"quarter",
|
35
|
+
"second",
|
36
|
+
"timezone",
|
37
|
+
"timezone_hour",
|
38
|
+
"timezone_minute",
|
39
|
+
"week",
|
40
|
+
"year",
|
41
|
+
]
|
42
|
+
|
43
|
+
|
44
|
+
class Extract(QueryString):
|
45
|
+
def __init__(
|
46
|
+
self,
|
47
|
+
identifier: t.Union[Date, Time, Timestamp, Timestamptz, QueryString],
|
48
|
+
datetime_component: ExtractComponent,
|
49
|
+
alias: t.Optional[str] = None,
|
50
|
+
):
|
51
|
+
"""
|
52
|
+
.. note:: This is for Postgres / Cockroach only.
|
53
|
+
|
54
|
+
Extract a date or time component from a ``Date`` / ``Time`` /
|
55
|
+
``Timestamp`` / ``Timestamptz`` column. For example, getting the month
|
56
|
+
from a timestamp:
|
57
|
+
|
58
|
+
.. code-block:: python
|
59
|
+
|
60
|
+
>>> from piccolo.query.functions import Extract
|
61
|
+
>>> await Concert.select(
|
62
|
+
... Extract(Concert.starts, "month", alias="start_month")
|
63
|
+
... )
|
64
|
+
[{"start_month": 12}]
|
65
|
+
|
66
|
+
:param identifier:
|
67
|
+
Identifies the column.
|
68
|
+
:param datetime_component:
|
69
|
+
The date or time component to extract from the column.
|
70
|
+
|
71
|
+
"""
|
72
|
+
if datetime_component.lower() not in t.get_args(ExtractComponent):
|
73
|
+
raise ValueError("The date time component isn't recognised.")
|
74
|
+
|
75
|
+
super().__init__(
|
76
|
+
f"EXTRACT({datetime_component} FROM {{}})",
|
77
|
+
identifier,
|
78
|
+
alias=alias,
|
79
|
+
)
|
80
|
+
|
81
|
+
|
82
|
+
###############################################################################
|
83
|
+
# SQLite
|
84
|
+
|
85
|
+
|
86
|
+
class Strftime(QueryString):
|
87
|
+
def __init__(
|
88
|
+
self,
|
89
|
+
identifier: t.Union[Date, Time, Timestamp, Timestamptz, QueryString],
|
90
|
+
datetime_format: str,
|
91
|
+
alias: t.Optional[str] = None,
|
92
|
+
):
|
93
|
+
"""
|
94
|
+
.. note:: This is for SQLite only.
|
95
|
+
|
96
|
+
Format a datetime value. For example:
|
97
|
+
|
98
|
+
.. code-block:: python
|
99
|
+
|
100
|
+
>>> from piccolo.query.functions import Strftime
|
101
|
+
>>> await Concert.select(
|
102
|
+
... Strftime(Concert.starts, "%Y", alias="start_year")
|
103
|
+
... )
|
104
|
+
[{"start_month": "2024"}]
|
105
|
+
|
106
|
+
:param identifier:
|
107
|
+
Identifies the column.
|
108
|
+
:param datetime_format:
|
109
|
+
A string describing the output format (see SQLite's
|
110
|
+
`documentation <https://www.sqlite.org/lang_datefunc.html>`_
|
111
|
+
for more info).
|
112
|
+
|
113
|
+
"""
|
114
|
+
super().__init__(
|
115
|
+
f"strftime('{datetime_format}', {{}})",
|
116
|
+
identifier,
|
117
|
+
alias=alias,
|
118
|
+
)
|
119
|
+
|
120
|
+
|
121
|
+
###############################################################################
|
122
|
+
# Database agnostic
|
123
|
+
|
124
|
+
|
125
|
+
def _get_engine_type(identifier: t.Union[Column, QueryString]) -> str:
|
126
|
+
if isinstance(identifier, Column):
|
127
|
+
return identifier._meta.engine_type
|
128
|
+
elif isinstance(identifier, QueryString) and (
|
129
|
+
columns := identifier.columns
|
130
|
+
):
|
131
|
+
return columns[0]._meta.engine_type
|
132
|
+
else:
|
133
|
+
raise ValueError("Unable to determine the engine type")
|
134
|
+
|
135
|
+
|
136
|
+
def _extract_component(
|
137
|
+
identifier: t.Union[Date, Time, Timestamp, Timestamptz, QueryString],
|
138
|
+
sqlite_format: str,
|
139
|
+
postgres_format: ExtractComponent,
|
140
|
+
alias: t.Optional[str],
|
141
|
+
) -> QueryString:
|
142
|
+
engine_type = _get_engine_type(identifier=identifier)
|
143
|
+
|
144
|
+
return Cast(
|
145
|
+
(
|
146
|
+
Strftime(
|
147
|
+
identifier=identifier,
|
148
|
+
datetime_format=sqlite_format,
|
149
|
+
)
|
150
|
+
if engine_type == "sqlite"
|
151
|
+
else Extract(
|
152
|
+
identifier=identifier,
|
153
|
+
datetime_component=postgres_format,
|
154
|
+
)
|
155
|
+
),
|
156
|
+
Integer(),
|
157
|
+
alias=alias,
|
158
|
+
)
|
159
|
+
|
160
|
+
|
161
|
+
def Year(
|
162
|
+
identifier: t.Union[Date, Timestamp, Timestamptz, QueryString],
|
163
|
+
alias: t.Optional[str] = None,
|
164
|
+
) -> QueryString:
|
165
|
+
"""
|
166
|
+
Extract the year as an integer.
|
167
|
+
"""
|
168
|
+
return _extract_component(
|
169
|
+
identifier=identifier,
|
170
|
+
sqlite_format="%Y",
|
171
|
+
postgres_format="year",
|
172
|
+
alias=alias,
|
173
|
+
)
|
174
|
+
|
175
|
+
|
176
|
+
def Month(
|
177
|
+
identifier: t.Union[Date, Timestamp, Timestamptz, QueryString],
|
178
|
+
alias: t.Optional[str] = None,
|
179
|
+
) -> QueryString:
|
180
|
+
"""
|
181
|
+
Extract the month as an integer.
|
182
|
+
"""
|
183
|
+
return _extract_component(
|
184
|
+
identifier=identifier,
|
185
|
+
sqlite_format="%m",
|
186
|
+
postgres_format="month",
|
187
|
+
alias=alias,
|
188
|
+
)
|
189
|
+
|
190
|
+
|
191
|
+
def Day(
|
192
|
+
identifier: t.Union[Date, Timestamp, Timestamptz, QueryString],
|
193
|
+
alias: t.Optional[str] = None,
|
194
|
+
) -> QueryString:
|
195
|
+
"""
|
196
|
+
Extract the day as an integer.
|
197
|
+
"""
|
198
|
+
return _extract_component(
|
199
|
+
identifier=identifier,
|
200
|
+
sqlite_format="%d",
|
201
|
+
postgres_format="day",
|
202
|
+
alias=alias,
|
203
|
+
)
|
204
|
+
|
205
|
+
|
206
|
+
def Hour(
|
207
|
+
identifier: t.Union[Time, Timestamp, Timestamptz, QueryString],
|
208
|
+
alias: t.Optional[str] = None,
|
209
|
+
) -> QueryString:
|
210
|
+
"""
|
211
|
+
Extract the hour as an integer.
|
212
|
+
"""
|
213
|
+
return _extract_component(
|
214
|
+
identifier=identifier,
|
215
|
+
sqlite_format="%H",
|
216
|
+
postgres_format="hour",
|
217
|
+
alias=alias,
|
218
|
+
)
|
219
|
+
|
220
|
+
|
221
|
+
def Minute(
|
222
|
+
identifier: t.Union[Time, Timestamp, Timestamptz, QueryString],
|
223
|
+
alias: t.Optional[str] = None,
|
224
|
+
) -> QueryString:
|
225
|
+
"""
|
226
|
+
Extract the minute as an integer.
|
227
|
+
"""
|
228
|
+
return _extract_component(
|
229
|
+
identifier=identifier,
|
230
|
+
sqlite_format="%M",
|
231
|
+
postgres_format="minute",
|
232
|
+
alias=alias,
|
233
|
+
)
|
234
|
+
|
235
|
+
|
236
|
+
def Second(
|
237
|
+
identifier: t.Union[Time, Timestamp, Timestamptz, QueryString],
|
238
|
+
alias: t.Optional[str] = None,
|
239
|
+
) -> QueryString:
|
240
|
+
"""
|
241
|
+
Extract the second as an integer.
|
242
|
+
"""
|
243
|
+
return _extract_component(
|
244
|
+
identifier=identifier,
|
245
|
+
sqlite_format="%S",
|
246
|
+
postgres_format="second",
|
247
|
+
alias=alias,
|
248
|
+
)
|
249
|
+
|
250
|
+
|
251
|
+
__all__ = (
|
252
|
+
"Extract",
|
253
|
+
"Strftime",
|
254
|
+
"Year",
|
255
|
+
"Month",
|
256
|
+
"Day",
|
257
|
+
"Hour",
|
258
|
+
"Minute",
|
259
|
+
"Second",
|
260
|
+
)
|
@@ -0,0 +1,118 @@
|
|
1
|
+
"""
|
2
|
+
These functions mirror their counterparts in the Postgresql docs:
|
3
|
+
|
4
|
+
https://www.postgresql.org/docs/current/functions-string.html
|
5
|
+
|
6
|
+
"""
|
7
|
+
|
8
|
+
import typing as t
|
9
|
+
|
10
|
+
from piccolo.columns.base import Column
|
11
|
+
from piccolo.columns.column_types import Text, Varchar
|
12
|
+
from piccolo.querystring import QueryString
|
13
|
+
|
14
|
+
from .base import Function
|
15
|
+
|
16
|
+
|
17
|
+
class Length(Function):
|
18
|
+
"""
|
19
|
+
Returns the number of characters in the string.
|
20
|
+
"""
|
21
|
+
|
22
|
+
function_name = "LENGTH"
|
23
|
+
|
24
|
+
|
25
|
+
class Lower(Function):
|
26
|
+
"""
|
27
|
+
Converts the string to all lower case, according to the rules of the
|
28
|
+
database's locale.
|
29
|
+
"""
|
30
|
+
|
31
|
+
function_name = "LOWER"
|
32
|
+
|
33
|
+
|
34
|
+
class Ltrim(Function):
|
35
|
+
"""
|
36
|
+
Removes the longest string containing only characters in characters (a
|
37
|
+
space by default) from the start of string.
|
38
|
+
"""
|
39
|
+
|
40
|
+
function_name = "LTRIM"
|
41
|
+
|
42
|
+
|
43
|
+
class Reverse(Function):
|
44
|
+
"""
|
45
|
+
Return reversed string.
|
46
|
+
|
47
|
+
Not supported in SQLite.
|
48
|
+
|
49
|
+
"""
|
50
|
+
|
51
|
+
function_name = "REVERSE"
|
52
|
+
|
53
|
+
|
54
|
+
class Rtrim(Function):
|
55
|
+
"""
|
56
|
+
Removes the longest string containing only characters in characters (a
|
57
|
+
space by default) from the end of string.
|
58
|
+
"""
|
59
|
+
|
60
|
+
function_name = "RTRIM"
|
61
|
+
|
62
|
+
|
63
|
+
class Upper(Function):
|
64
|
+
"""
|
65
|
+
Converts the string to all upper case, according to the rules of the
|
66
|
+
database's locale.
|
67
|
+
"""
|
68
|
+
|
69
|
+
function_name = "UPPER"
|
70
|
+
|
71
|
+
|
72
|
+
class Concat(QueryString):
|
73
|
+
def __init__(
|
74
|
+
self,
|
75
|
+
*args: t.Union[Column, QueryString, str],
|
76
|
+
alias: t.Optional[str] = None,
|
77
|
+
):
|
78
|
+
"""
|
79
|
+
Concatenate multiple values into a single string.
|
80
|
+
|
81
|
+
.. note::
|
82
|
+
Null values are ignored, so ``null + '!!!'`` returns ``!!!``,
|
83
|
+
not ``null``.
|
84
|
+
|
85
|
+
.. warning::
|
86
|
+
For SQLite, this is only available in version 3.44.0 and above.
|
87
|
+
|
88
|
+
"""
|
89
|
+
if len(args) < 2:
|
90
|
+
raise ValueError("At least two values must be passed in.")
|
91
|
+
|
92
|
+
placeholders = ", ".join("{}" for _ in args)
|
93
|
+
|
94
|
+
processed_args: t.List[t.Union[QueryString, Column]] = []
|
95
|
+
|
96
|
+
for arg in args:
|
97
|
+
if isinstance(arg, str) or (
|
98
|
+
isinstance(arg, Column)
|
99
|
+
and not isinstance(arg, (Varchar, Text))
|
100
|
+
):
|
101
|
+
processed_args.append(QueryString("CAST({} AS TEXT)", arg))
|
102
|
+
else:
|
103
|
+
processed_args.append(arg)
|
104
|
+
|
105
|
+
super().__init__(
|
106
|
+
f"CONCAT({placeholders})", *processed_args, alias=alias
|
107
|
+
)
|
108
|
+
|
109
|
+
|
110
|
+
__all__ = (
|
111
|
+
"Length",
|
112
|
+
"Lower",
|
113
|
+
"Ltrim",
|
114
|
+
"Reverse",
|
115
|
+
"Rtrim",
|
116
|
+
"Upper",
|
117
|
+
"Concat",
|
118
|
+
)
|
@@ -162,6 +162,7 @@ piccolo/query/proxy.py
|
|
162
162
|
piccolo/query/functions/__init__.py
|
163
163
|
piccolo/query/functions/aggregate.py
|
164
164
|
piccolo/query/functions/base.py
|
165
|
+
piccolo/query/functions/datetime.py
|
165
166
|
piccolo/query/functions/math.py
|
166
167
|
piccolo/query/functions/string.py
|
167
168
|
piccolo/query/functions/type_conversion.py
|
@@ -315,6 +316,7 @@ tests/query/test_querystring.py
|
|
315
316
|
tests/query/test_slots.py
|
316
317
|
tests/query/functions/__init__.py
|
317
318
|
tests/query/functions/base.py
|
319
|
+
tests/query/functions/test_datetime.py
|
318
320
|
tests/query/functions/test_functions.py
|
319
321
|
tests/query/functions/test_math.py
|
320
322
|
tests/query/functions/test_string.py
|
@@ -0,0 +1,114 @@
|
|
1
|
+
import datetime
|
2
|
+
|
3
|
+
from piccolo.columns import Timestamp
|
4
|
+
from piccolo.query.functions.datetime import (
|
5
|
+
Day,
|
6
|
+
Extract,
|
7
|
+
Hour,
|
8
|
+
Minute,
|
9
|
+
Month,
|
10
|
+
Second,
|
11
|
+
Strftime,
|
12
|
+
Year,
|
13
|
+
)
|
14
|
+
from piccolo.table import Table
|
15
|
+
from tests.base import engines_only, sqlite_only
|
16
|
+
|
17
|
+
from .base import FunctionTest
|
18
|
+
|
19
|
+
|
20
|
+
class Concert(Table):
|
21
|
+
starts = Timestamp()
|
22
|
+
|
23
|
+
|
24
|
+
class DatetimeTest(FunctionTest):
|
25
|
+
tables = [Concert]
|
26
|
+
|
27
|
+
def setUp(self) -> None:
|
28
|
+
super().setUp()
|
29
|
+
self.concert = Concert(
|
30
|
+
{
|
31
|
+
Concert.starts: datetime.datetime(
|
32
|
+
year=2024, month=6, day=14, hour=23, minute=46, second=10
|
33
|
+
)
|
34
|
+
}
|
35
|
+
)
|
36
|
+
self.concert.save().run_sync()
|
37
|
+
|
38
|
+
|
39
|
+
@engines_only("postgres", "cockroach")
|
40
|
+
class TestExtract(DatetimeTest):
|
41
|
+
def test_extract(self):
|
42
|
+
self.assertEqual(
|
43
|
+
Concert.select(
|
44
|
+
Extract(Concert.starts, "year", alias="starts_year")
|
45
|
+
).run_sync(),
|
46
|
+
[{"starts_year": self.concert.starts.year}],
|
47
|
+
)
|
48
|
+
|
49
|
+
def test_invalid_format(self):
|
50
|
+
with self.assertRaises(ValueError):
|
51
|
+
Extract(
|
52
|
+
Concert.starts,
|
53
|
+
"abc123", # type: ignore
|
54
|
+
alias="starts_year",
|
55
|
+
)
|
56
|
+
|
57
|
+
|
58
|
+
@sqlite_only
|
59
|
+
class TestStrftime(DatetimeTest):
|
60
|
+
def test_strftime(self):
|
61
|
+
self.assertEqual(
|
62
|
+
Concert.select(
|
63
|
+
Strftime(Concert.starts, "%Y", alias="starts_year")
|
64
|
+
).run_sync(),
|
65
|
+
[{"starts_year": str(self.concert.starts.year)}],
|
66
|
+
)
|
67
|
+
|
68
|
+
|
69
|
+
class TestDatabaseAgnostic(DatetimeTest):
|
70
|
+
def test_year(self):
|
71
|
+
self.assertEqual(
|
72
|
+
Concert.select(
|
73
|
+
Year(Concert.starts, alias="starts_year")
|
74
|
+
).run_sync(),
|
75
|
+
[{"starts_year": self.concert.starts.year}],
|
76
|
+
)
|
77
|
+
|
78
|
+
def test_month(self):
|
79
|
+
self.assertEqual(
|
80
|
+
Concert.select(
|
81
|
+
Month(Concert.starts, alias="starts_month")
|
82
|
+
).run_sync(),
|
83
|
+
[{"starts_month": self.concert.starts.month}],
|
84
|
+
)
|
85
|
+
|
86
|
+
def test_day(self):
|
87
|
+
self.assertEqual(
|
88
|
+
Concert.select(Day(Concert.starts, alias="starts_day")).run_sync(),
|
89
|
+
[{"starts_day": self.concert.starts.day}],
|
90
|
+
)
|
91
|
+
|
92
|
+
def test_hour(self):
|
93
|
+
self.assertEqual(
|
94
|
+
Concert.select(
|
95
|
+
Hour(Concert.starts, alias="starts_hour")
|
96
|
+
).run_sync(),
|
97
|
+
[{"starts_hour": self.concert.starts.hour}],
|
98
|
+
)
|
99
|
+
|
100
|
+
def test_minute(self):
|
101
|
+
self.assertEqual(
|
102
|
+
Concert.select(
|
103
|
+
Minute(Concert.starts, alias="starts_minute")
|
104
|
+
).run_sync(),
|
105
|
+
[{"starts_minute": self.concert.starts.minute}],
|
106
|
+
)
|
107
|
+
|
108
|
+
def test_second(self):
|
109
|
+
self.assertEqual(
|
110
|
+
Concert.select(
|
111
|
+
Second(Concert.starts, alias="starts_second")
|
112
|
+
).run_sync(),
|
113
|
+
[{"starts_second": self.concert.starts.second}],
|
114
|
+
)
|