piccolo 1.14.0__tar.gz → 1.16.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.14.0 → piccolo-1.16.0}/PKG-INFO +1 -1
- piccolo-1.16.0/piccolo/__init__.py +1 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/tables.py +6 -2
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/base.py +1 -3
- piccolo-1.16.0/piccolo/query/methods/refresh.py +186 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/select.py +3 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/table.py +8 -2
- piccolo-1.16.0/piccolo/testing/test_case.py +120 -0
- piccolo-1.16.0/piccolo/utils/encoding.py +74 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo.egg-info/PKG-INFO +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo.egg-info/SOURCES.txt +2 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/user/test_tables.py +12 -4
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/m2m/test_m2m.py +7 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_array.py +2 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_bigint.py +2 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_boolean.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_bytea.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_choices.py +2 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_date.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_double_precision.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_interval.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_json.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_jsonb.py +2 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_numeric.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_primary_key.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_readable.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_real.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_reference.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_reserved_column_names.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_smallint.py +2 -2
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_time.py +2 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_timestamp.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_timestamptz.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_uuid.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_varchar.py +2 -2
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/functions/base.py +1 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/functions/test_datetime.py +2 -1
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/functions/test_math.py +1 -1
- piccolo-1.16.0/tests/table/test_refresh.py +298 -0
- piccolo-1.16.0/tests/testing/test_test_case.py +65 -0
- piccolo-1.14.0/piccolo/__init__.py +0 -1
- piccolo-1.14.0/piccolo/query/methods/refresh.py +0 -105
- piccolo-1.14.0/piccolo/utils/encoding.py +0 -33
- piccolo-1.14.0/tests/table/test_refresh.py +0 -87
- {piccolo-1.14.0 → piccolo-1.16.0}/LICENSE +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/README.md +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/app/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/app/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/app/commands/new.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/app/commands/show_all.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/app/commands/templates/piccolo_app.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/app/commands/templates/tables.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/app/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/new.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/README.md.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/_blacksheep_app.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/_esmerald_app.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/_fastapi_app.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/_lilya_app.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/_litestar_app.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/_starlette_app.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/app.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/conftest.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/__init__.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/_blacksheep_endpoints.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/_esmerald_endpoints.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/_lilya_endpoints.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/_litestar_endpoints.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/_starlette_endpoints.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_app.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_migrations/README.md +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/tables.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/templates/base.html.jinja_raw +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/main.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf_test.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/requirements.txt.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/static/favicon.ico +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/commands/templates/app/static/main.css +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/asgi/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/fixtures/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/fixtures/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/fixtures/commands/dump.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/fixtures/commands/load.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/fixtures/commands/shared.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/fixtures/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/meta/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/meta/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/meta/commands/version.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/meta/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/auto/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/auto/diffable_table.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/auto/migration_manager.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/auto/operations.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/auto/schema_differ.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/auto/schema_snapshot.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/auto/serialisation.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/auto/serialisation_legacy.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/commands/backwards.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/commands/base.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/commands/check.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/commands/clean.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/commands/forwards.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/commands/new.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/commands/templates/migration.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/migrations/tables.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/playground/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/playground/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/playground/commands/run.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/playground/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/project/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/project/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/project/commands/new.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/project/commands/templates/piccolo_conf.py.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/project/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/schema/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/schema/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/schema/commands/exceptions.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/schema/commands/generate.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/schema/commands/graph.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/schema/commands/templates/graphviz.dot.jinja +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/schema/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/shell/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/shell/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/shell/commands/run.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/shell/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/sql_shell/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/sql_shell/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/sql_shell/commands/run.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/sql_shell/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/tester/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/tester/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/tester/commands/run.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/tester/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/commands/change_password.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/commands/change_permissions.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/commands/create.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/commands/list.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/piccolo_migrations/2019-11-14T21-52-21.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/piccolo_migrations/2020-06-11T21-38-55.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/piccolo_migrations/2021-04-30T16-14-15.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/apps/user/piccolo_migrations/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/base.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/choices.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/column_types.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/combination.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/defaults/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/defaults/base.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/defaults/date.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/defaults/interval.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/defaults/time.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/defaults/timestamp.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/defaults/timestamptz.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/defaults/uuid.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/indexes.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/m2m.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/operators/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/operators/base.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/operators/comparison.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/operators/math.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/operators/string.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/readable.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/columns/reference.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/conf/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/conf/apps.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/custom_types.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/engine/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/engine/base.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/engine/cockroach.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/engine/exceptions.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/engine/finder.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/engine/postgres.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/engine/sqlite.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/main.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/py.typed +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/functions/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/functions/aggregate.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/functions/base.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/functions/datetime.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/functions/math.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/functions/string.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/functions/type_conversion.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/alter.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/count.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/create.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/create_index.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/delete.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/drop_index.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/exists.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/indexes.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/insert.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/objects.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/raw.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/table_exists.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/methods/update.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/mixins.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/query/proxy.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/querystring.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/schema.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/table_reflection.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/testing/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/testing/model_builder.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/testing/random_builder.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/dictionary.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/graphlib/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/graphlib/_graphlib.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/lazy_loader.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/list.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/naming.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/objects.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/printing.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/pydantic.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/repr.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/sql_values.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/sync.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo/utils/warnings.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo.egg-info/dependency_links.txt +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo.egg-info/entry_points.txt +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo.egg-info/requires.txt +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/piccolo.egg-info/top_level.txt +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/profiling/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/profiling/run_profile.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/pyproject.toml +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/setup.cfg +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/setup.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/app/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/app/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/app/commands/test_new.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/app/commands/test_show_all.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/asgi/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/asgi/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/asgi/commands/test_new.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/fixtures/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/fixtures/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/fixtures/commands/test_dump_load.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/fixtures/commands/test_shared.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/meta/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/meta/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/meta/commands/test_version.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/auto/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/auto/integration/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/auto/integration/test_migrations.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/auto/test_diffable_table.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/auto/test_migration_manager.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/auto/test_schema_differ.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/auto/test_schema_snapshot.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/auto/test_serialisation.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/commands/test_base.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/commands/test_check.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/commands/test_clean.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/commands/test_forwards_backwards.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/commands/test_migrations/2020-03-31T20-38-22.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/commands/test_migrations/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/commands/test_new.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/migrations/test_migration.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/project/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/project/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/project/commands/test_new.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/schema/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/shell/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/shell/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/shell/commands/test_run.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/sql_shell/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/sql_shell/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/sql_shell/commands/test_run.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/tester/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/user/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/user/commands/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/user/commands/test_change_password.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/user/commands/test_change_permissions.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/user/commands/test_create.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/apps/user/commands/test_list.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/m2m/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/m2m/base.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/m2m/test_m2m_schema.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_base.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_combination.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_db_column_name.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_defaults.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/columns/test_get_sql_value.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/conf/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/conf/example.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/conf/test_apps.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/engine/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/engine/test_extra_nodes.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/engine/test_logging.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/engine/test_nested_transaction.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/engine/test_pool.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/engine/test_transaction.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/engine/test_version_parsing.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/mega/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/mega/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/mega/piccolo_migrations/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/mega/tables.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/music/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/music/piccolo_app.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/music/tables.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/example_apps/music/tables_detailed.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/functions/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/functions/test_functions.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/functions/test_string.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/functions/test_type_conversion.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/mixins/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/mixins/test_columns_delegate.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/mixins/test_order_by_delegate.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/test_await.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/test_camelcase.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/test_freeze.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/test_gather.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/test_querystring.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/query/test_slots.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/instance/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/instance/test_create.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/instance/test_get_related.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/instance/test_get_related_readable.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/instance/test_instantiate.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/instance/test_remove.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/instance/test_save.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/instance/test_to_dict.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_all_columns.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_alter.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_batch.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_callback.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_constructor.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_count.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_create.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_create_db_tables.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_create_table_class.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_delete.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_drop_db_tables.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_exists.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_from_dict.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_indexes.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_inheritance.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_insert.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_join.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_join_on.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_metaclass.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_objects.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_output.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_raw.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_ref.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_repr.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_select.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_str.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_table_exists.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/table/test_update.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/test_main.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/test_schema.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/testing/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/testing/test_model_builder.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/testing/test_random_builder.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/__init__.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_dictionary.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_encoding.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_lazy_loader.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_list.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_naming.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_printing.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_pydantic.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_sql_values.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_sync.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_table_reflection.py +0 -0
- {piccolo-1.14.0 → piccolo-1.16.0}/tests/utils/test_warnings.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "1.16.0"
|
@@ -91,10 +91,14 @@ class BaseUser(Table, tablename="piccolo_user"):
|
|
91
91
|
raise ValueError("A password must be provided.")
|
92
92
|
|
93
93
|
if len(password) < cls._min_password_length:
|
94
|
-
raise ValueError(
|
94
|
+
raise ValueError(
|
95
|
+
f"The password is too short. (min {cls._min_password_length})"
|
96
|
+
)
|
95
97
|
|
96
98
|
if len(password) > cls._max_password_length:
|
97
|
-
raise ValueError(
|
99
|
+
raise ValueError(
|
100
|
+
f"The password is too long. (max {cls._max_password_length})"
|
101
|
+
)
|
98
102
|
|
99
103
|
if password.startswith("pbkdf2_sha256"):
|
100
104
|
logger.warning(
|
@@ -79,9 +79,7 @@ class Query(t.Generic[TableInstance, QueryResponseType]):
|
|
79
79
|
if column._alias is not None:
|
80
80
|
json_column_names.append(column._alias)
|
81
81
|
elif len(column._meta.call_chain) > 0:
|
82
|
-
json_column_names.append(
|
83
|
-
column._meta.get_default_alias().replace("$", ".")
|
84
|
-
)
|
82
|
+
json_column_names.append(column._meta.get_default_alias())
|
85
83
|
else:
|
86
84
|
json_column_names.append(column._meta.name)
|
87
85
|
|
@@ -0,0 +1,186 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import typing as t
|
4
|
+
|
5
|
+
from piccolo.utils.encoding import JSONDict
|
6
|
+
from piccolo.utils.sync import run_sync
|
7
|
+
|
8
|
+
if t.TYPE_CHECKING: # pragma: no cover
|
9
|
+
from piccolo.columns import Column
|
10
|
+
from piccolo.table import Table
|
11
|
+
|
12
|
+
|
13
|
+
class Refresh:
|
14
|
+
"""
|
15
|
+
Used to refresh :class:`Table <piccolo.table.Table>` instances with the
|
16
|
+
latest data data from the database. Accessible via
|
17
|
+
:meth:`refresh <piccolo.table.Table.refresh>`.
|
18
|
+
|
19
|
+
:param instance:
|
20
|
+
The instance to refresh.
|
21
|
+
:param columns:
|
22
|
+
Which columns to refresh - it not specified, then all columns are
|
23
|
+
refreshed.
|
24
|
+
:param load_json:
|
25
|
+
Whether to load ``JSON`` / ``JSONB`` columns as objects, instead of
|
26
|
+
just a string.
|
27
|
+
|
28
|
+
"""
|
29
|
+
|
30
|
+
def __init__(
|
31
|
+
self,
|
32
|
+
instance: Table,
|
33
|
+
columns: t.Optional[t.Sequence[Column]] = None,
|
34
|
+
load_json: bool = False,
|
35
|
+
):
|
36
|
+
self.instance = instance
|
37
|
+
|
38
|
+
if columns:
|
39
|
+
for column in columns:
|
40
|
+
if len(column._meta.call_chain) > 0:
|
41
|
+
raise ValueError(
|
42
|
+
"We can't currently selectively refresh certain "
|
43
|
+
"columns on child objects (e.g. Concert.band_1.name). "
|
44
|
+
"Please just specify top level columns (e.g. "
|
45
|
+
"Concert.band_1), and the entire child object will be "
|
46
|
+
"refreshed."
|
47
|
+
)
|
48
|
+
|
49
|
+
self.columns = columns
|
50
|
+
self.load_json = load_json
|
51
|
+
|
52
|
+
@property
|
53
|
+
def _columns(self) -> t.Sequence[Column]:
|
54
|
+
"""
|
55
|
+
Works out which columns the user wants to refresh.
|
56
|
+
"""
|
57
|
+
if self.columns:
|
58
|
+
return self.columns
|
59
|
+
|
60
|
+
return [
|
61
|
+
i for i in self.instance._meta.columns if not i._meta.primary_key
|
62
|
+
]
|
63
|
+
|
64
|
+
def _get_columns(self, instance: Table, columns: t.Sequence[Column]):
|
65
|
+
"""
|
66
|
+
If `prefetch` was used on the object, for example::
|
67
|
+
|
68
|
+
>>> await Band.objects(Band.manager)
|
69
|
+
|
70
|
+
We should also update the prefetched object.
|
71
|
+
|
72
|
+
It works multiple level deep. If we refresh this::
|
73
|
+
|
74
|
+
>>> await Album.objects(Album.band.manager).first()
|
75
|
+
|
76
|
+
It will update the nested `band` object, and also the `manager`
|
77
|
+
object.
|
78
|
+
|
79
|
+
"""
|
80
|
+
from piccolo.columns.column_types import ForeignKey
|
81
|
+
from piccolo.table import Table
|
82
|
+
|
83
|
+
select_columns = []
|
84
|
+
|
85
|
+
for column in columns:
|
86
|
+
if isinstance(column, ForeignKey) and isinstance(
|
87
|
+
(child_instance := getattr(instance, column._meta.name)),
|
88
|
+
Table,
|
89
|
+
):
|
90
|
+
select_columns.extend(
|
91
|
+
self._get_columns(
|
92
|
+
child_instance,
|
93
|
+
# Fetch all columns (even the primary key, just in
|
94
|
+
# case the foreign key now references a different row).
|
95
|
+
column.all_columns(),
|
96
|
+
)
|
97
|
+
)
|
98
|
+
else:
|
99
|
+
select_columns.append(column)
|
100
|
+
|
101
|
+
return select_columns
|
102
|
+
|
103
|
+
def _update_instance(self, instance: Table, data_dict: t.Dict):
|
104
|
+
"""
|
105
|
+
Update the table instance. It is called recursively, if the instance
|
106
|
+
has child instances.
|
107
|
+
"""
|
108
|
+
for key, value in data_dict.items():
|
109
|
+
if isinstance(value, dict) and not isinstance(value, JSONDict):
|
110
|
+
# If the value is a dict, then it's a child instance.
|
111
|
+
if all(i is None for i in value.values()):
|
112
|
+
# If all values in the nested object are None, then we can
|
113
|
+
# safely assume that the object itself is null, as the
|
114
|
+
# primary key value must be null.
|
115
|
+
setattr(instance, key, None)
|
116
|
+
else:
|
117
|
+
self._update_instance(getattr(instance, key), value)
|
118
|
+
else:
|
119
|
+
setattr(instance, key, value)
|
120
|
+
|
121
|
+
async def run(
|
122
|
+
self, in_pool: bool = True, node: t.Optional[str] = None
|
123
|
+
) -> Table:
|
124
|
+
"""
|
125
|
+
Run it asynchronously. For example::
|
126
|
+
|
127
|
+
await my_instance.refresh().run()
|
128
|
+
|
129
|
+
# or for convenience:
|
130
|
+
await my_instance.refresh()
|
131
|
+
|
132
|
+
Modifies the instance in place, but also returns it as a convenience.
|
133
|
+
|
134
|
+
"""
|
135
|
+
instance = self.instance
|
136
|
+
|
137
|
+
if not instance._exists_in_db:
|
138
|
+
raise ValueError("The instance doesn't exist in the database.")
|
139
|
+
|
140
|
+
pk_column = instance._meta.primary_key
|
141
|
+
|
142
|
+
primary_key_value = getattr(instance, pk_column._meta.name, None)
|
143
|
+
|
144
|
+
if primary_key_value is None:
|
145
|
+
raise ValueError("The instance's primary key value isn't defined.")
|
146
|
+
|
147
|
+
columns = self._columns
|
148
|
+
if not columns:
|
149
|
+
raise ValueError("No columns to fetch.")
|
150
|
+
|
151
|
+
select_columns = self._get_columns(
|
152
|
+
instance=self.instance, columns=columns
|
153
|
+
)
|
154
|
+
|
155
|
+
data_dict = (
|
156
|
+
await instance.__class__.select(*select_columns)
|
157
|
+
.where(pk_column == primary_key_value)
|
158
|
+
.output(nested=True, load_json=self.load_json)
|
159
|
+
.first()
|
160
|
+
.run(node=node, in_pool=in_pool)
|
161
|
+
)
|
162
|
+
|
163
|
+
if data_dict is None:
|
164
|
+
raise ValueError(
|
165
|
+
"The object doesn't exist in the database any more."
|
166
|
+
)
|
167
|
+
|
168
|
+
self._update_instance(instance=instance, data_dict=data_dict)
|
169
|
+
|
170
|
+
return instance
|
171
|
+
|
172
|
+
def __await__(self):
|
173
|
+
"""
|
174
|
+
If the user doesn't explicity call :meth:`run`, proxy to it as a
|
175
|
+
convenience.
|
176
|
+
"""
|
177
|
+
return self.run().__await__()
|
178
|
+
|
179
|
+
def run_sync(self, *args, **kwargs) -> Table:
|
180
|
+
"""
|
181
|
+
Run it synchronously. For example::
|
182
|
+
|
183
|
+
my_instance.refresh().run_sync()
|
184
|
+
|
185
|
+
"""
|
186
|
+
return run_sync(self.run(*args, **kwargs))
|
@@ -406,6 +406,9 @@ class Select(Query[TableInstance, t.List[t.Dict[str, t.Any]]]):
|
|
406
406
|
def output(self: Self, *, load_json: bool, as_list: bool) -> SelectJSON: # type: ignore # noqa: E501
|
407
407
|
...
|
408
408
|
|
409
|
+
@t.overload
|
410
|
+
def output(self: Self, *, load_json: bool, nested: bool) -> Self: ...
|
411
|
+
|
409
412
|
@t.overload
|
410
413
|
def output(self: Self, *, nested: bool) -> Self: ...
|
411
414
|
|
@@ -541,7 +541,9 @@ class Table(metaclass=TableMetaclass):
|
|
541
541
|
)
|
542
542
|
|
543
543
|
def refresh(
|
544
|
-
self,
|
544
|
+
self,
|
545
|
+
columns: t.Optional[t.Sequence[Column]] = None,
|
546
|
+
load_json: bool = False,
|
545
547
|
) -> Refresh:
|
546
548
|
"""
|
547
549
|
Used to fetch the latest data for this instance from the database.
|
@@ -551,6 +553,10 @@ class Table(metaclass=TableMetaclass):
|
|
551
553
|
If you only want to refresh certain columns, specify them here.
|
552
554
|
Otherwise all columns are refreshed.
|
553
555
|
|
556
|
+
:param load_json:
|
557
|
+
Whether to load ``JSON`` / ``JSONB`` columns as objects, instead of
|
558
|
+
just a string.
|
559
|
+
|
554
560
|
Example usage::
|
555
561
|
|
556
562
|
# Get an instance from the database.
|
@@ -564,7 +570,7 @@ class Table(metaclass=TableMetaclass):
|
|
564
570
|
instance.refresh().run_sync()
|
565
571
|
|
566
572
|
"""
|
567
|
-
return Refresh(instance=self, columns=columns)
|
573
|
+
return Refresh(instance=self, columns=columns, load_json=load_json)
|
568
574
|
|
569
575
|
@t.overload
|
570
576
|
def get_related(
|
@@ -0,0 +1,120 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import typing as t
|
4
|
+
from unittest import IsolatedAsyncioTestCase, TestCase
|
5
|
+
|
6
|
+
from piccolo.engine import Engine, engine_finder
|
7
|
+
from piccolo.table import (
|
8
|
+
Table,
|
9
|
+
create_db_tables,
|
10
|
+
create_db_tables_sync,
|
11
|
+
drop_db_tables,
|
12
|
+
drop_db_tables_sync,
|
13
|
+
)
|
14
|
+
|
15
|
+
|
16
|
+
class TableTest(TestCase):
|
17
|
+
"""
|
18
|
+
Identical to :class:`AsyncTableTest <piccolo.testing.test_case.AsyncTableTest>`,
|
19
|
+
except it only work for sync tests. Only use this if you can't make your
|
20
|
+
tests async (perhaps you're on Python 3.7 where ``IsolatedAsyncioTestCase``
|
21
|
+
isn't available).
|
22
|
+
|
23
|
+
For example::
|
24
|
+
|
25
|
+
class TestBand(TableTest):
|
26
|
+
tables = [Band]
|
27
|
+
|
28
|
+
def test_band(self):
|
29
|
+
...
|
30
|
+
|
31
|
+
""" # noqa: E501
|
32
|
+
|
33
|
+
tables: t.List[t.Type[Table]]
|
34
|
+
|
35
|
+
def setUp(self) -> None:
|
36
|
+
create_db_tables_sync(*self.tables)
|
37
|
+
|
38
|
+
def tearDown(self) -> None:
|
39
|
+
drop_db_tables_sync(*self.tables)
|
40
|
+
|
41
|
+
|
42
|
+
class AsyncTableTest(IsolatedAsyncioTestCase):
|
43
|
+
"""
|
44
|
+
Used for tests where we need to create Piccolo tables - they will
|
45
|
+
automatically be created and dropped.
|
46
|
+
|
47
|
+
For example::
|
48
|
+
|
49
|
+
class TestBand(AsyncTableTest):
|
50
|
+
tables = [Band]
|
51
|
+
|
52
|
+
async def test_band(self):
|
53
|
+
...
|
54
|
+
|
55
|
+
"""
|
56
|
+
|
57
|
+
tables: t.List[t.Type[Table]]
|
58
|
+
|
59
|
+
async def asyncSetUp(self) -> None:
|
60
|
+
await create_db_tables(*self.tables)
|
61
|
+
|
62
|
+
async def asyncTearDown(self) -> None:
|
63
|
+
await drop_db_tables(*self.tables)
|
64
|
+
|
65
|
+
|
66
|
+
class AsyncTransactionTest(IsolatedAsyncioTestCase):
|
67
|
+
"""
|
68
|
+
Wraps each test in a transaction, which is automatically rolled back when
|
69
|
+
the test finishes.
|
70
|
+
|
71
|
+
.. warning::
|
72
|
+
Python 3.11 and above only.
|
73
|
+
|
74
|
+
If your test suite just contains ``AsyncTransactionTest`` tests, then you
|
75
|
+
can setup your database tables once before your test suite runs. Any
|
76
|
+
changes made to your tables by the tests will be rolled back automatically.
|
77
|
+
|
78
|
+
Here's an example::
|
79
|
+
|
80
|
+
from piccolo.testing.test_case import AsyncTransactionTest
|
81
|
+
|
82
|
+
|
83
|
+
class TestBandEndpoint(AsyncTransactionTest):
|
84
|
+
|
85
|
+
async def test_band_response(self):
|
86
|
+
\"\"\"
|
87
|
+
Make sure the endpoint returns a 200.
|
88
|
+
\"\"\"
|
89
|
+
band = Band({Band.name: "Pythonistas"})
|
90
|
+
await band.save()
|
91
|
+
|
92
|
+
# Using an API testing client, like httpx:
|
93
|
+
response = await client.get(f"/bands/{band.id}/")
|
94
|
+
self.assertEqual(response.status_code, 200)
|
95
|
+
|
96
|
+
We add a ``Band`` to the database, but any subsequent tests won't see it,
|
97
|
+
as the changes are rolled back automatically.
|
98
|
+
|
99
|
+
"""
|
100
|
+
|
101
|
+
# We use `engine_finder` to find the current `Engine`, but you can
|
102
|
+
# explicity set it here if you prefer:
|
103
|
+
#
|
104
|
+
# class MyTest(AsyncTransactionTest):
|
105
|
+
# db = DB
|
106
|
+
#
|
107
|
+
# ...
|
108
|
+
#
|
109
|
+
db: t.Optional[Engine] = None
|
110
|
+
|
111
|
+
async def asyncSetUp(self) -> None:
|
112
|
+
db = self.db or engine_finder()
|
113
|
+
assert db is not None
|
114
|
+
self.transaction = db.transaction()
|
115
|
+
# This is only available in Python 3.11 and above:
|
116
|
+
await self.enterAsyncContext(cm=self.transaction) # type: ignore
|
117
|
+
|
118
|
+
async def asyncTearDown(self):
|
119
|
+
await super().asyncTearDown()
|
120
|
+
await self.transaction.rollback()
|
@@ -0,0 +1,74 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
import typing as t
|
4
|
+
|
5
|
+
try:
|
6
|
+
import orjson
|
7
|
+
|
8
|
+
ORJSON = True
|
9
|
+
except ImportError:
|
10
|
+
import json
|
11
|
+
|
12
|
+
ORJSON = False
|
13
|
+
|
14
|
+
|
15
|
+
def dump_json(data: t.Any, pretty: bool = False) -> str:
|
16
|
+
if ORJSON:
|
17
|
+
orjson_params: t.Dict[str, t.Any] = {"default": str}
|
18
|
+
if pretty:
|
19
|
+
orjson_params["option"] = (
|
20
|
+
orjson.OPT_INDENT_2 | orjson.OPT_APPEND_NEWLINE # type: ignore
|
21
|
+
)
|
22
|
+
return orjson.dumps(data, **orjson_params).decode( # type: ignore
|
23
|
+
"utf8"
|
24
|
+
)
|
25
|
+
else:
|
26
|
+
params: t.Dict[str, t.Any] = {"default": str}
|
27
|
+
if pretty:
|
28
|
+
params["indent"] = 2
|
29
|
+
return json.dumps(data, **params) # type: ignore
|
30
|
+
|
31
|
+
|
32
|
+
class JSONDict(dict):
|
33
|
+
"""
|
34
|
+
Once we have parsed a JSON string into a dictionary, we can't distinguish
|
35
|
+
it from other dictionaries.
|
36
|
+
|
37
|
+
Sometimes we might want to - for example::
|
38
|
+
|
39
|
+
>>> await Album.select(
|
40
|
+
... Album.all_columns(),
|
41
|
+
... Album.recording_studio.all_columns()
|
42
|
+
... ).output(
|
43
|
+
... nested=True,
|
44
|
+
... load_json=True
|
45
|
+
... )
|
46
|
+
|
47
|
+
[{
|
48
|
+
'id': 1,
|
49
|
+
'band': 1,
|
50
|
+
'name': 'Awesome album 1',
|
51
|
+
'recorded_at': {
|
52
|
+
'id': 1,
|
53
|
+
'facilities': {'restaurant': True, 'mixing_desk': True},
|
54
|
+
'name': 'Abbey Road'
|
55
|
+
},
|
56
|
+
'release_date': datetime.date(2021, 1, 1)
|
57
|
+
}]
|
58
|
+
|
59
|
+
Facilities could be mistaken for a table.
|
60
|
+
|
61
|
+
"""
|
62
|
+
|
63
|
+
...
|
64
|
+
|
65
|
+
|
66
|
+
def load_json(data: str) -> t.Any:
|
67
|
+
response = (
|
68
|
+
orjson.loads(data) if ORJSON else json.loads(data) # type: ignore
|
69
|
+
)
|
70
|
+
|
71
|
+
if isinstance(response, dict):
|
72
|
+
return JSONDict(**response)
|
73
|
+
|
74
|
+
return response
|
@@ -185,6 +185,7 @@ piccolo/query/methods/update.py
|
|
185
185
|
piccolo/testing/__init__.py
|
186
186
|
piccolo/testing/model_builder.py
|
187
187
|
piccolo/testing/random_builder.py
|
188
|
+
piccolo/testing/test_case.py
|
188
189
|
piccolo/utils/__init__.py
|
189
190
|
piccolo/utils/dictionary.py
|
190
191
|
piccolo/utils/encoding.py
|
@@ -365,6 +366,7 @@ tests/table/instance/test_to_dict.py
|
|
365
366
|
tests/testing/__init__.py
|
366
367
|
tests/testing/test_model_builder.py
|
367
368
|
tests/testing/test_random_builder.py
|
369
|
+
tests/testing/test_test_case.py
|
368
370
|
tests/utils/__init__.py
|
369
371
|
tests/utils/test_dictionary.py
|
370
372
|
tests/utils/test_encoding.py
|
@@ -109,7 +109,7 @@ class TestLogin(TestCase):
|
|
109
109
|
BaseUser.update_password_sync(username, malicious_password)
|
110
110
|
self.assertEqual(
|
111
111
|
manager.exception.__str__(),
|
112
|
-
"The password is too long.",
|
112
|
+
f"The password is too long. (max {BaseUser._max_password_length})",
|
113
113
|
)
|
114
114
|
|
115
115
|
# Test short passwords
|
@@ -118,7 +118,10 @@ class TestLogin(TestCase):
|
|
118
118
|
BaseUser.update_password_sync(username, short_password)
|
119
119
|
self.assertEqual(
|
120
120
|
manager.exception.__str__(),
|
121
|
-
|
121
|
+
(
|
122
|
+
"The password is too short. (min "
|
123
|
+
f"{BaseUser._min_password_length})"
|
124
|
+
),
|
122
125
|
)
|
123
126
|
|
124
127
|
# Test no password
|
@@ -205,7 +208,11 @@ class TestCreateUser(TestCase):
|
|
205
208
|
BaseUser.create_user_sync(username="bob", password="abc")
|
206
209
|
|
207
210
|
self.assertEqual(
|
208
|
-
manager.exception.__str__(),
|
211
|
+
manager.exception.__str__(),
|
212
|
+
(
|
213
|
+
"The password is too short. (min "
|
214
|
+
f"{BaseUser._min_password_length})"
|
215
|
+
),
|
209
216
|
)
|
210
217
|
|
211
218
|
def test_long_password_error(self):
|
@@ -216,7 +223,8 @@ class TestCreateUser(TestCase):
|
|
216
223
|
)
|
217
224
|
|
218
225
|
self.assertEqual(
|
219
|
-
manager.exception.__str__(),
|
226
|
+
manager.exception.__str__(),
|
227
|
+
f"The password is too long. (max {BaseUser._max_password_length})",
|
220
228
|
)
|
221
229
|
|
222
230
|
def test_no_username_error(self):
|
@@ -4,6 +4,7 @@ import decimal
|
|
4
4
|
import uuid
|
5
5
|
from unittest import TestCase
|
6
6
|
|
7
|
+
from piccolo.utils.encoding import JSONDict
|
7
8
|
from tests.base import engines_skip
|
8
9
|
|
9
10
|
try:
|
@@ -376,6 +377,9 @@ class TestM2MComplexSchema(TestCase):
|
|
376
377
|
|
377
378
|
if isinstance(column, UUID):
|
378
379
|
self.assertIn(type(returned_value), (uuid.UUID, asyncpgUUID))
|
380
|
+
elif isinstance(column, (JSON, JSONB)):
|
381
|
+
self.assertEqual(type(returned_value), JSONDict)
|
382
|
+
self.assertEqual(original_value, returned_value)
|
379
383
|
else:
|
380
384
|
self.assertEqual(
|
381
385
|
type(original_value),
|
@@ -401,6 +405,9 @@ class TestM2MComplexSchema(TestCase):
|
|
401
405
|
if isinstance(column, UUID):
|
402
406
|
self.assertIn(type(returned_value), (uuid.UUID, asyncpgUUID))
|
403
407
|
self.assertEqual(str(original_value), str(returned_value))
|
408
|
+
elif isinstance(column, (JSON, JSONB)):
|
409
|
+
self.assertEqual(type(returned_value), JSONDict)
|
410
|
+
self.assertEqual(original_value, returned_value)
|
404
411
|
else:
|
405
412
|
self.assertEqual(
|
406
413
|
type(original_value),
|
@@ -14,7 +14,8 @@ from piccolo.columns.column_types import (
|
|
14
14
|
)
|
15
15
|
from piccolo.querystring import QueryString
|
16
16
|
from piccolo.table import Table
|
17
|
-
from
|
17
|
+
from piccolo.testing.test_case import TableTest
|
18
|
+
from tests.base import engines_only, engines_skip, sqlite_only
|
18
19
|
|
19
20
|
|
20
21
|
class MyTable(Table):
|
@@ -2,7 +2,8 @@ import enum
|
|
2
2
|
|
3
3
|
from piccolo.columns.column_types import Array, Varchar
|
4
4
|
from piccolo.table import Table
|
5
|
-
from
|
5
|
+
from piccolo.testing.test_case import TableTest
|
6
|
+
from tests.base import engines_only
|
6
7
|
from tests.example_apps.music.tables import Shirt
|
7
8
|
|
8
9
|
|
@@ -3,7 +3,7 @@ import datetime
|
|
3
3
|
from piccolo.columns.column_types import Interval
|
4
4
|
from piccolo.columns.defaults.interval import IntervalCustom
|
5
5
|
from piccolo.table import Table
|
6
|
-
from
|
6
|
+
from piccolo.testing.test_case import TableTest
|
7
7
|
|
8
8
|
|
9
9
|
class MyTable(Table):
|
@@ -1,6 +1,7 @@
|
|
1
1
|
from piccolo.columns.column_types import JSONB, ForeignKey, Varchar
|
2
2
|
from piccolo.table import Table
|
3
|
-
from
|
3
|
+
from piccolo.testing.test_case import TableTest
|
4
|
+
from tests.base import engines_only, engines_skip
|
4
5
|
|
5
6
|
|
6
7
|
class RecordingStudio(Table):
|