piccolo 1.6.0__tar.gz → 1.8.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.6.0 → piccolo-1.8.0}/PKG-INFO +1 -1
- piccolo-1.8.0/piccolo/__init__.py +1 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/base.py +4 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/column_types.py +26 -5
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/engine/sqlite.py +171 -57
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/functions/__init__.py +2 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/functions/aggregate.py +12 -12
- piccolo-1.8.0/piccolo/query/functions/type_conversion.py +82 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/querystring.py +12 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo.egg-info/PKG-INFO +1 -1
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo.egg-info/SOURCES.txt +1 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/auto/integration/test_migrations.py +28 -5
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/auto/test_migration_manager.py +15 -15
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_array.py +89 -2
- piccolo-1.8.0/tests/query/test_functions.py +238 -0
- piccolo-1.6.0/piccolo/__init__.py +0 -1
- piccolo-1.6.0/tests/query/test_functions.py +0 -102
- {piccolo-1.6.0 → piccolo-1.8.0}/LICENSE +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/README.md +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/app/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/app/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/app/commands/new.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/app/commands/show_all.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/app/commands/templates/piccolo_app.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/app/commands/templates/tables.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/app/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/new.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/README.md.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/_blacksheep_app.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/_esmerald_app.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/_fastapi_app.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/_lilya_app.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/_litestar_app.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/_starlette_app.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/app.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/conftest.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/__init__.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/_blacksheep_endpoints.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/_esmerald_endpoints.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/_lilya_endpoints.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/_litestar_endpoints.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/_starlette_endpoints.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_app.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_migrations/README.md +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/tables.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/templates/base.html.jinja_raw +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/main.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf_test.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/requirements.txt.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/static/favicon.ico +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/commands/templates/app/static/main.css +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/asgi/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/fixtures/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/fixtures/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/fixtures/commands/dump.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/fixtures/commands/load.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/fixtures/commands/shared.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/fixtures/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/meta/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/meta/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/meta/commands/version.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/meta/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/auto/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/auto/diffable_table.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/auto/migration_manager.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/auto/operations.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/auto/schema_differ.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/auto/schema_snapshot.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/auto/serialisation.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/auto/serialisation_legacy.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/commands/backwards.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/commands/base.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/commands/check.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/commands/clean.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/commands/forwards.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/commands/new.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/commands/templates/migration.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/migrations/tables.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/playground/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/playground/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/playground/commands/run.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/playground/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/project/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/project/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/project/commands/new.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/project/commands/templates/piccolo_conf.py.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/project/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/schema/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/schema/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/schema/commands/exceptions.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/schema/commands/generate.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/schema/commands/graph.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/schema/commands/templates/graphviz.dot.jinja +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/schema/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/shell/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/shell/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/shell/commands/run.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/shell/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/sql_shell/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/sql_shell/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/sql_shell/commands/run.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/sql_shell/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/tester/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/tester/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/tester/commands/run.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/tester/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/commands/change_password.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/commands/change_permissions.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/commands/create.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/commands/list.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/piccolo_migrations/2019-11-14T21-52-21.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/piccolo_migrations/2020-06-11T21-38-55.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/piccolo_migrations/2021-04-30T16-14-15.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/piccolo_migrations/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/apps/user/tables.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/choices.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/combination.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/defaults/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/defaults/base.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/defaults/date.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/defaults/interval.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/defaults/time.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/defaults/timestamp.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/defaults/timestamptz.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/defaults/uuid.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/indexes.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/m2m.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/operators/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/operators/base.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/operators/comparison.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/operators/math.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/operators/string.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/readable.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/columns/reference.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/conf/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/conf/apps.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/custom_types.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/engine/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/engine/base.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/engine/cockroach.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/engine/exceptions.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/engine/finder.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/engine/postgres.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/main.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/py.typed +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/base.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/functions/base.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/functions/string.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/alter.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/count.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/create.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/create_index.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/delete.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/drop_index.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/exists.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/indexes.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/insert.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/objects.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/raw.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/refresh.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/select.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/table_exists.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/methods/update.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/mixins.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/query/proxy.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/schema.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/table.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/table_reflection.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/testing/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/testing/model_builder.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/testing/random_builder.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/dictionary.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/encoding.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/graphlib/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/graphlib/_graphlib.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/lazy_loader.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/list.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/naming.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/objects.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/printing.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/pydantic.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/repr.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/sql_values.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/sync.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo/utils/warnings.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo.egg-info/dependency_links.txt +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo.egg-info/entry_points.txt +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo.egg-info/requires.txt +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/piccolo.egg-info/top_level.txt +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/profiling/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/profiling/run_profile.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/pyproject.toml +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/setup.cfg +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/setup.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/app/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/app/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/app/commands/test_new.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/app/commands/test_show_all.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/asgi/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/asgi/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/asgi/commands/test_new.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/fixtures/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/fixtures/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/fixtures/commands/test_dump_load.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/fixtures/commands/test_shared.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/meta/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/meta/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/meta/commands/test_version.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/auto/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/auto/integration/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/auto/test_diffable_table.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/auto/test_schema_differ.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/auto/test_schema_snapshot.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/auto/test_serialisation.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/commands/test_base.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/commands/test_check.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/commands/test_clean.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/commands/test_forwards_backwards.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/commands/test_migrations/2020-03-31T20-38-22.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/commands/test_migrations/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/commands/test_new.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/migrations/test_migration.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/project/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/project/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/project/commands/test_new.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/schema/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/shell/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/shell/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/shell/commands/test_run.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/sql_shell/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/sql_shell/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/sql_shell/commands/test_run.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/tester/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/user/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/user/commands/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/user/commands/test_change_password.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/user/commands/test_change_permissions.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/user/commands/test_create.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/user/commands/test_list.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/apps/user/test_tables.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/m2m/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/m2m/base.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/m2m/test_m2m.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/m2m/test_m2m_schema.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_base.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_bigint.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_boolean.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_bytea.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_choices.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_combination.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_date.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_db_column_name.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_defaults.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_double_precision.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_interval.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_json.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_jsonb.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_numeric.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_primary_key.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_readable.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_real.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_reference.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_reserved_column_names.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_smallint.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_time.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_timestamp.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_timestamptz.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_uuid.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/columns/test_varchar.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/conf/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/conf/example.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/conf/test_apps.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/engine/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/engine/test_extra_nodes.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/engine/test_logging.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/engine/test_nested_transaction.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/engine/test_pool.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/engine/test_transaction.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/engine/test_version_parsing.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/mega/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/mega/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/mega/piccolo_migrations/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/mega/tables.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/music/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/music/piccolo_app.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/music/tables.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/example_apps/music/tables_detailed.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/mixins/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/mixins/test_columns_delegate.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/mixins/test_order_by_delegate.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/test_await.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/test_camelcase.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/test_freeze.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/test_gather.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/test_querystring.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/query/test_slots.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/instance/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/instance/test_create.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/instance/test_get_related.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/instance/test_get_related_readable.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/instance/test_instantiate.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/instance/test_remove.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/instance/test_save.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/instance/test_to_dict.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_all_columns.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_alter.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_batch.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_callback.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_constructor.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_count.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_create.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_create_db_tables.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_create_table_class.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_delete.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_drop_db_tables.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_exists.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_from_dict.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_indexes.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_inheritance.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_insert.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_join.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_join_on.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_metaclass.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_objects.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_output.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_raw.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_ref.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_refresh.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_repr.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_select.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_str.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_table_exists.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/table/test_update.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/test_main.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/test_schema.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/testing/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/testing/test_model_builder.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/testing/test_random_builder.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/__init__.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_dictionary.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_encoding.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_lazy_loader.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_list.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_naming.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_printing.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_pydantic.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_sql_values.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_sync.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_table_reflection.py +0 -0
- {piccolo-1.6.0 → piccolo-1.8.0}/tests/utils/test_warnings.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "1.8.0"
|
@@ -201,6 +201,10 @@ class ColumnMeta:
|
|
201
201
|
)
|
202
202
|
return self._table
|
203
203
|
|
204
|
+
@table.setter
|
205
|
+
def table(self, value: t.Type[Table]):
|
206
|
+
self._table = value
|
207
|
+
|
204
208
|
###########################################################################
|
205
209
|
|
206
210
|
# Used by Foreign Keys:
|
@@ -2532,7 +2532,14 @@ class Array(Column):
|
|
2532
2532
|
if engine_type in ("postgres", "cockroach"):
|
2533
2533
|
return f"{self.base_column.column_type}[]"
|
2534
2534
|
elif engine_type == "sqlite":
|
2535
|
-
|
2535
|
+
inner_column = self._get_inner_column()
|
2536
|
+
return (
|
2537
|
+
f"ARRAY_{inner_column.column_type}"
|
2538
|
+
if isinstance(
|
2539
|
+
inner_column, (Date, Timestamp, Timestamptz, Time)
|
2540
|
+
)
|
2541
|
+
else "ARRAY"
|
2542
|
+
)
|
2536
2543
|
raise Exception("Unrecognized engine type")
|
2537
2544
|
|
2538
2545
|
def _setup_base_column(self, table_class: t.Type[Table]):
|
@@ -2564,6 +2571,23 @@ class Array(Column):
|
|
2564
2571
|
else:
|
2565
2572
|
return start + 1
|
2566
2573
|
|
2574
|
+
def _get_inner_column(self) -> Column:
|
2575
|
+
"""
|
2576
|
+
A helper function to get the innermost ``Column`` for the array. For
|
2577
|
+
example::
|
2578
|
+
|
2579
|
+
>>> Array(Varchar())._get_inner_column()
|
2580
|
+
Varchar
|
2581
|
+
|
2582
|
+
>>> Array(Array(Varchar()))._get_inner_column()
|
2583
|
+
Varchar
|
2584
|
+
|
2585
|
+
"""
|
2586
|
+
if isinstance(self.base_column, Array):
|
2587
|
+
return self.base_column._get_inner_column()
|
2588
|
+
else:
|
2589
|
+
return self.base_column
|
2590
|
+
|
2567
2591
|
def _get_inner_value_type(self) -> t.Type:
|
2568
2592
|
"""
|
2569
2593
|
A helper function to get the innermost value type for the array. For
|
@@ -2576,10 +2600,7 @@ class Array(Column):
|
|
2576
2600
|
str
|
2577
2601
|
|
2578
2602
|
"""
|
2579
|
-
|
2580
|
-
return self.base_column._get_inner_value_type()
|
2581
|
-
else:
|
2582
|
-
return self.base_column.value_type
|
2603
|
+
return self._get_inner_column().value_type
|
2583
2604
|
|
2584
2605
|
def __getitem__(self, value: int) -> Array:
|
2585
2606
|
"""
|
@@ -9,6 +9,7 @@ import typing as t
|
|
9
9
|
import uuid
|
10
10
|
from dataclasses import dataclass
|
11
11
|
from decimal import Decimal
|
12
|
+
from functools import partial, wraps
|
12
13
|
|
13
14
|
from piccolo.engine.base import Batch, Engine, validate_savepoint_name
|
14
15
|
from piccolo.engine.exceptions import TransactionError
|
@@ -35,14 +36,14 @@ if t.TYPE_CHECKING: # pragma: no cover
|
|
35
36
|
# In
|
36
37
|
|
37
38
|
|
38
|
-
def convert_numeric_in(value):
|
39
|
+
def convert_numeric_in(value: Decimal) -> float:
|
39
40
|
"""
|
40
41
|
Convert any Decimal values into floats.
|
41
42
|
"""
|
42
43
|
return float(value)
|
43
44
|
|
44
45
|
|
45
|
-
def convert_uuid_in(value) -> str:
|
46
|
+
def convert_uuid_in(value: uuid.UUID) -> str:
|
46
47
|
"""
|
47
48
|
Converts the UUID value being passed into sqlite.
|
48
49
|
"""
|
@@ -56,7 +57,7 @@ def convert_time_in(value: datetime.time) -> str:
|
|
56
57
|
return value.isoformat()
|
57
58
|
|
58
59
|
|
59
|
-
def convert_date_in(value: datetime.date):
|
60
|
+
def convert_date_in(value: datetime.date) -> str:
|
60
61
|
"""
|
61
62
|
Converts the date value being passed into sqlite.
|
62
63
|
"""
|
@@ -74,122 +75,235 @@ def convert_datetime_in(value: datetime.datetime) -> str:
|
|
74
75
|
return str(value)
|
75
76
|
|
76
77
|
|
77
|
-
def convert_timedelta_in(value: datetime.timedelta):
|
78
|
+
def convert_timedelta_in(value: datetime.timedelta) -> float:
|
78
79
|
"""
|
79
80
|
Converts the timedelta value being passed into sqlite.
|
80
81
|
"""
|
81
82
|
return value.total_seconds()
|
82
83
|
|
83
84
|
|
84
|
-
def convert_array_in(value: list):
|
85
|
+
def convert_array_in(value: list) -> str:
|
85
86
|
"""
|
86
|
-
Converts a list value into a string
|
87
|
+
Converts a list value into a string (it handles nested lists, and type like
|
88
|
+
dateime/ time / date which aren't usually JSON serialisable.).
|
89
|
+
|
87
90
|
"""
|
88
|
-
if value and type(value[0]) not in [str, int, float, list]:
|
89
|
-
raise ValueError("Can only serialise str, int, float, and list.")
|
90
91
|
|
91
|
-
|
92
|
+
def serialise(data: list):
|
93
|
+
output = []
|
94
|
+
|
95
|
+
for item in data:
|
96
|
+
if isinstance(item, list):
|
97
|
+
output.append(serialise(item))
|
98
|
+
elif isinstance(
|
99
|
+
item, (datetime.datetime, datetime.time, datetime.date)
|
100
|
+
):
|
101
|
+
if adapter := ADAPTERS.get(type(item)):
|
102
|
+
output.append(adapter(item))
|
103
|
+
else:
|
104
|
+
raise ValueError("The adapter wasn't found.")
|
105
|
+
elif item is None or isinstance(item, (str, int, float, list)):
|
106
|
+
# We can safely JSON serialise these.
|
107
|
+
output.append(item)
|
108
|
+
else:
|
109
|
+
raise ValueError("We can't currently serialise this value.")
|
110
|
+
|
111
|
+
return output
|
112
|
+
|
113
|
+
return dump_json(serialise(value))
|
114
|
+
|
115
|
+
|
116
|
+
###############################################################################
|
117
|
+
|
118
|
+
# Register adapters
|
119
|
+
|
120
|
+
ADAPTERS: t.Dict[t.Type, t.Callable[[t.Any], t.Any]] = {
|
121
|
+
Decimal: convert_numeric_in,
|
122
|
+
uuid.UUID: convert_uuid_in,
|
123
|
+
datetime.time: convert_time_in,
|
124
|
+
datetime.date: convert_date_in,
|
125
|
+
datetime.datetime: convert_datetime_in,
|
126
|
+
datetime.timedelta: convert_timedelta_in,
|
127
|
+
list: convert_array_in,
|
128
|
+
}
|
92
129
|
|
130
|
+
for value_type, adapter in ADAPTERS.items():
|
131
|
+
sqlite3.register_adapter(value_type, adapter)
|
132
|
+
|
133
|
+
###############################################################################
|
93
134
|
|
94
135
|
# Out
|
95
136
|
|
96
137
|
|
97
|
-
def
|
138
|
+
def decode_to_string(converter: t.Callable[[str], t.Any]):
|
139
|
+
"""
|
140
|
+
This means we can use our converters with string and bytes. They are
|
141
|
+
passed bytes when used directly via SQLite, and are passed strings when
|
142
|
+
used by the array converters.
|
143
|
+
"""
|
144
|
+
|
145
|
+
@wraps(converter)
|
146
|
+
def wrapper(value: t.Union[str, bytes]) -> t.Any:
|
147
|
+
if isinstance(value, bytes):
|
148
|
+
return converter(value.decode("utf8"))
|
149
|
+
elif isinstance(value, str):
|
150
|
+
return converter(value)
|
151
|
+
else:
|
152
|
+
raise ValueError("Unsupported type")
|
153
|
+
|
154
|
+
return wrapper
|
155
|
+
|
156
|
+
|
157
|
+
@decode_to_string
|
158
|
+
def convert_numeric_out(value: str) -> Decimal:
|
98
159
|
"""
|
99
160
|
Convert float values into Decimals.
|
100
161
|
"""
|
101
|
-
return Decimal(value
|
162
|
+
return Decimal(value)
|
102
163
|
|
103
164
|
|
104
|
-
|
165
|
+
@decode_to_string
|
166
|
+
def convert_int_out(value: str) -> int:
|
105
167
|
"""
|
106
168
|
Make sure Integer values are actually of type int.
|
107
169
|
"""
|
108
170
|
return int(float(value))
|
109
171
|
|
110
172
|
|
111
|
-
|
173
|
+
@decode_to_string
|
174
|
+
def convert_uuid_out(value: str) -> uuid.UUID:
|
112
175
|
"""
|
113
176
|
If the value is a uuid, convert it to a UUID instance.
|
114
177
|
"""
|
115
|
-
return uuid.UUID(value
|
178
|
+
return uuid.UUID(value)
|
116
179
|
|
117
180
|
|
118
|
-
|
119
|
-
|
181
|
+
@decode_to_string
|
182
|
+
def convert_date_out(value: str) -> datetime.date:
|
183
|
+
return datetime.date.fromisoformat(value)
|
120
184
|
|
121
185
|
|
122
|
-
|
186
|
+
@decode_to_string
|
187
|
+
def convert_time_out(value: str) -> datetime.time:
|
123
188
|
"""
|
124
189
|
If the value is a time, convert it to a UUID instance.
|
125
190
|
"""
|
126
|
-
return datetime.time.fromisoformat(value
|
191
|
+
return datetime.time.fromisoformat(value)
|
127
192
|
|
128
193
|
|
129
|
-
|
194
|
+
@decode_to_string
|
195
|
+
def convert_seconds_out(value: str) -> datetime.timedelta:
|
130
196
|
"""
|
131
197
|
If the value is from a seconds column, convert it to a timedelta instance.
|
132
198
|
"""
|
133
|
-
return datetime.timedelta(seconds=float(value
|
199
|
+
return datetime.timedelta(seconds=float(value))
|
134
200
|
|
135
201
|
|
136
|
-
|
202
|
+
@decode_to_string
|
203
|
+
def convert_boolean_out(value: str) -> bool:
|
137
204
|
"""
|
138
205
|
If the value is from a boolean column, convert it to a bool value.
|
139
206
|
"""
|
140
|
-
|
141
|
-
return _value == "1"
|
207
|
+
return value == "1"
|
142
208
|
|
143
209
|
|
144
|
-
|
210
|
+
@decode_to_string
|
211
|
+
def convert_timestamp_out(value: str) -> datetime.datetime:
|
145
212
|
"""
|
146
213
|
If the value is from a timestamp column, convert it to a datetime value.
|
147
214
|
"""
|
148
|
-
return datetime.datetime.fromisoformat(value
|
215
|
+
return datetime.datetime.fromisoformat(value)
|
149
216
|
|
150
217
|
|
151
|
-
|
218
|
+
@decode_to_string
|
219
|
+
def convert_timestamptz_out(value: str) -> datetime.datetime:
|
152
220
|
"""
|
153
221
|
If the value is from a timestamptz column, convert it to a datetime value,
|
154
222
|
with a timezone of UTC.
|
155
223
|
"""
|
156
|
-
|
157
|
-
|
158
|
-
|
224
|
+
return datetime.datetime.fromisoformat(value).replace(
|
225
|
+
tzinfo=datetime.timezone.utc
|
226
|
+
)
|
159
227
|
|
160
228
|
|
161
|
-
|
229
|
+
@decode_to_string
|
230
|
+
def convert_array_out(value: str) -> t.List:
|
162
231
|
"""
|
163
232
|
If the value if from an array column, deserialise the string back into a
|
164
233
|
list.
|
165
234
|
"""
|
166
|
-
return load_json(value
|
167
|
-
|
168
|
-
|
169
|
-
def
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
235
|
+
return load_json(value)
|
236
|
+
|
237
|
+
|
238
|
+
def convert_complex_array_out(value: bytes, converter: t.Callable):
|
239
|
+
"""
|
240
|
+
This is used to handle arrays of things like timestamps, which we can't
|
241
|
+
just load from JSON without doing additional work to convert the elements
|
242
|
+
back into Python objects.
|
243
|
+
"""
|
244
|
+
parsed = load_json(value.decode("utf8"))
|
245
|
+
|
246
|
+
def convert_list(list_value: t.List):
|
247
|
+
output = []
|
248
|
+
|
249
|
+
for value in list_value:
|
250
|
+
if isinstance(value, list):
|
251
|
+
# For nested arrays
|
252
|
+
output.append(convert_list(value))
|
253
|
+
elif isinstance(value, str):
|
254
|
+
output.append(converter(value))
|
255
|
+
else:
|
256
|
+
output.append(value)
|
257
|
+
|
258
|
+
return output
|
259
|
+
|
260
|
+
if isinstance(parsed, list):
|
261
|
+
return convert_list(parsed)
|
262
|
+
else:
|
263
|
+
return parsed
|
264
|
+
|
265
|
+
|
266
|
+
@decode_to_string
|
267
|
+
def convert_M2M_out(value: str) -> t.List:
|
268
|
+
return value.split(",")
|
269
|
+
|
270
|
+
|
271
|
+
###############################################################################
|
272
|
+
# Register the basic converters
|
273
|
+
|
274
|
+
CONVERTERS = {
|
275
|
+
"NUMERIC": convert_numeric_out,
|
276
|
+
"INTEGER": convert_int_out,
|
277
|
+
"UUID": convert_uuid_out,
|
278
|
+
"DATE": convert_date_out,
|
279
|
+
"TIME": convert_time_out,
|
280
|
+
"SECONDS": convert_seconds_out,
|
281
|
+
"BOOLEAN": convert_boolean_out,
|
282
|
+
"TIMESTAMP": convert_timestamp_out,
|
283
|
+
"TIMESTAMPTZ": convert_timestamptz_out,
|
284
|
+
"M2M": convert_M2M_out,
|
285
|
+
}
|
286
|
+
|
287
|
+
for column_name, converter in CONVERTERS.items():
|
288
|
+
sqlite3.register_converter(column_name, converter)
|
289
|
+
|
290
|
+
###############################################################################
|
291
|
+
# Register the array converters
|
292
|
+
|
293
|
+
# The ARRAY column type handles values which can be easily serialised to and
|
294
|
+
# from JSON.
|
295
|
+
sqlite3.register_converter("ARRAY", convert_array_out)
|
296
|
+
|
297
|
+
# We have special column types for arrays of timestamps etc, as simply loading
|
298
|
+
# the JSON isn't sufficient.
|
299
|
+
for column_name in ("TIMESTAMP", "TIMESTAMPTZ", "DATE", "TIME"):
|
300
|
+
sqlite3.register_converter(
|
301
|
+
f"ARRAY_{column_name}",
|
302
|
+
partial(
|
303
|
+
convert_complex_array_out,
|
304
|
+
converter=CONVERTERS[column_name],
|
305
|
+
),
|
306
|
+
)
|
193
307
|
|
194
308
|
###############################################################################
|
195
309
|
|
@@ -12,17 +12,17 @@ class Avg(Function):
|
|
12
12
|
|
13
13
|
.. code-block:: python
|
14
14
|
|
15
|
-
await Band.select(Avg(Band.popularity))
|
15
|
+
await Band.select(Avg(Band.popularity))
|
16
16
|
|
17
17
|
# We can use an alias. These two are equivalent:
|
18
18
|
|
19
19
|
await Band.select(
|
20
20
|
Avg(Band.popularity, alias="popularity_avg")
|
21
|
-
)
|
21
|
+
)
|
22
22
|
|
23
23
|
await Band.select(
|
24
24
|
Avg(Band.popularity).as_alias("popularity_avg")
|
25
|
-
)
|
25
|
+
)
|
26
26
|
|
27
27
|
"""
|
28
28
|
|
@@ -103,17 +103,17 @@ class Min(Function):
|
|
103
103
|
|
104
104
|
.. code-block:: python
|
105
105
|
|
106
|
-
await Band.select(Min(Band.popularity))
|
106
|
+
await Band.select(Min(Band.popularity))
|
107
107
|
|
108
108
|
# We can use an alias. These two are equivalent:
|
109
109
|
|
110
110
|
await Band.select(
|
111
111
|
Min(Band.popularity, alias="popularity_min")
|
112
|
-
)
|
112
|
+
)
|
113
113
|
|
114
114
|
await Band.select(
|
115
115
|
Min(Band.popularity).as_alias("popularity_min")
|
116
|
-
)
|
116
|
+
)
|
117
117
|
|
118
118
|
"""
|
119
119
|
|
@@ -128,17 +128,17 @@ class Max(Function):
|
|
128
128
|
|
129
129
|
await Band.select(
|
130
130
|
Max(Band.popularity)
|
131
|
-
)
|
131
|
+
)
|
132
132
|
|
133
133
|
# We can use an alias. These two are equivalent:
|
134
134
|
|
135
135
|
await Band.select(
|
136
136
|
Max(Band.popularity, alias="popularity_max")
|
137
|
-
)
|
137
|
+
)
|
138
138
|
|
139
139
|
await Band.select(
|
140
140
|
Max(Band.popularity).as_alias("popularity_max")
|
141
|
-
)
|
141
|
+
)
|
142
142
|
|
143
143
|
"""
|
144
144
|
|
@@ -153,17 +153,17 @@ class Sum(Function):
|
|
153
153
|
|
154
154
|
await Band.select(
|
155
155
|
Sum(Band.popularity)
|
156
|
-
)
|
156
|
+
)
|
157
157
|
|
158
158
|
# We can use an alias. These two are equivalent:
|
159
159
|
|
160
160
|
await Band.select(
|
161
161
|
Sum(Band.popularity, alias="popularity_sum")
|
162
|
-
)
|
162
|
+
)
|
163
163
|
|
164
164
|
await Band.select(
|
165
165
|
Sum(Band.popularity).as_alias("popularity_sum")
|
166
|
-
)
|
166
|
+
)
|
167
167
|
|
168
168
|
"""
|
169
169
|
|
@@ -0,0 +1,82 @@
|
|
1
|
+
import typing as t
|
2
|
+
|
3
|
+
from piccolo.columns.base import Column
|
4
|
+
from piccolo.querystring import QueryString
|
5
|
+
|
6
|
+
|
7
|
+
class Cast(QueryString):
|
8
|
+
def __init__(
|
9
|
+
self,
|
10
|
+
identifier: t.Union[Column, QueryString],
|
11
|
+
as_type: Column,
|
12
|
+
alias: t.Optional[str] = None,
|
13
|
+
):
|
14
|
+
"""
|
15
|
+
Cast a value to a different type. For example::
|
16
|
+
|
17
|
+
>>> from piccolo.query.functions import Cast
|
18
|
+
|
19
|
+
>>> await Concert.select(
|
20
|
+
... Cast(Concert.starts, Time(), "start_time")
|
21
|
+
... )
|
22
|
+
[{"start_time": datetime.time(19, 0)}]
|
23
|
+
|
24
|
+
:param identifier:
|
25
|
+
Identifies what is being converted (e.g. a column).
|
26
|
+
:param as_type:
|
27
|
+
The type to be converted to.
|
28
|
+
|
29
|
+
"""
|
30
|
+
# Make sure the identifier is a supported type.
|
31
|
+
|
32
|
+
if not isinstance(identifier, (Column, QueryString)):
|
33
|
+
raise ValueError(
|
34
|
+
"The identifier is an unsupported type - only Column and "
|
35
|
+
"QueryString instances are allowed."
|
36
|
+
)
|
37
|
+
|
38
|
+
#######################################################################
|
39
|
+
# Convert `as_type` to a string which can be used in the query.
|
40
|
+
|
41
|
+
if not isinstance(as_type, Column):
|
42
|
+
raise ValueError("The `as_type` value must be a Column instance.")
|
43
|
+
|
44
|
+
# We need to give the column a reference to a table, and hence
|
45
|
+
# the database engine, as the column type is sometimes dependent
|
46
|
+
# on which database is being used.
|
47
|
+
from piccolo.table import Table, create_table_class
|
48
|
+
|
49
|
+
table: t.Optional[t.Type[Table]] = None
|
50
|
+
|
51
|
+
if isinstance(identifier, Column):
|
52
|
+
table = identifier._meta.table
|
53
|
+
elif isinstance(identifier, QueryString):
|
54
|
+
table = (
|
55
|
+
identifier.columns[0]._meta.table
|
56
|
+
if identifier.columns
|
57
|
+
else None
|
58
|
+
)
|
59
|
+
|
60
|
+
as_type._meta.table = table or create_table_class("Table")
|
61
|
+
as_type_string = as_type.column_type
|
62
|
+
|
63
|
+
#######################################################################
|
64
|
+
# Preserve the original alias from the column.
|
65
|
+
|
66
|
+
if isinstance(identifier, Column):
|
67
|
+
alias = (
|
68
|
+
alias
|
69
|
+
or identifier._alias
|
70
|
+
or identifier._meta.get_default_alias()
|
71
|
+
)
|
72
|
+
|
73
|
+
#######################################################################
|
74
|
+
|
75
|
+
super().__init__(
|
76
|
+
f"CAST({{}} AS {as_type_string})",
|
77
|
+
identifier,
|
78
|
+
alias=alias,
|
79
|
+
)
|
80
|
+
|
81
|
+
|
82
|
+
__all__ = ("Cast",)
|
@@ -270,6 +270,18 @@ class QueryString(Selectable):
|
|
270
270
|
def __sub__(self, value) -> QueryString:
|
271
271
|
return QueryString("{} - {}", self, value)
|
272
272
|
|
273
|
+
def __gt__(self, value) -> QueryString:
|
274
|
+
return QueryString("{} > {}", self, value)
|
275
|
+
|
276
|
+
def __ge__(self, value) -> QueryString:
|
277
|
+
return QueryString("{} >= {}", self, value)
|
278
|
+
|
279
|
+
def __lt__(self, value) -> QueryString:
|
280
|
+
return QueryString("{} < {}", self, value)
|
281
|
+
|
282
|
+
def __le__(self, value) -> QueryString:
|
283
|
+
return QueryString("{} <= {}", self, value)
|
284
|
+
|
273
285
|
def is_in(self, value) -> QueryString:
|
274
286
|
return QueryString("{} IN {}", self, value)
|
275
287
|
|
@@ -163,6 +163,7 @@ piccolo/query/functions/__init__.py
|
|
163
163
|
piccolo/query/functions/aggregate.py
|
164
164
|
piccolo/query/functions/base.py
|
165
165
|
piccolo/query/functions/string.py
|
166
|
+
piccolo/query/functions/type_conversion.py
|
166
167
|
piccolo/query/methods/__init__.py
|
167
168
|
piccolo/query/methods/alter.py
|
168
169
|
piccolo/query/methods/count.py
|