piccolo 0.113.0__tar.gz → 0.115.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-0.113.0 → piccolo-0.115.0}/PKG-INFO +1 -1
- piccolo-0.115.0/piccolo/__init__.py +1 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/commands/load.py +47 -6
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/migration_manager.py +1 -1
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/m2m.py +11 -7
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/count.py +26 -11
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/select.py +67 -28
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/table.py +43 -5
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/PKG-INFO +1 -1
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/SOURCES.txt +4 -1
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/fixtures/commands/test_dump_load.py +39 -1
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/integration/test_migrations.py +34 -2
- piccolo-0.113.0/tests/columns/test_m2m.py → piccolo-0.115.0/tests/columns/m2m/base.py +55 -426
- piccolo-0.115.0/tests/columns/m2m/test_m2m.py +436 -0
- piccolo-0.115.0/tests/columns/m2m/test_m2m_schema.py +48 -0
- piccolo-0.115.0/tests/table/test_count.py +77 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_objects.py +4 -1
- piccolo-0.115.0/tests/utils/__init__.py +0 -0
- piccolo-0.113.0/piccolo/__init__.py +0 -1
- piccolo-0.113.0/tests/table/test_count.py +0 -11
- {piccolo-0.113.0 → piccolo-0.115.0}/README.md +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/new.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/show_all.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/templates/piccolo_app.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/templates/tables.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/new.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/README.md.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/_blacksheep_app.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/_fastapi_app.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/_litestar_app.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/_starlette_app.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/app.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/conftest.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/__init__.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/_blacksheep_endpoints.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/_litestar_endpoints.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/_starlette_endpoints.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_app.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_migrations/README.md +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/tables.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/templates/base.html.jinja_raw +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/main.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf_test.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/requirements.txt.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/static/favicon.ico +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/static/main.css +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/commands/dump.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/commands/shared.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/meta/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/meta/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/meta/commands/version.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/meta/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/diffable_table.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/operations.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/schema_differ.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/schema_snapshot.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/serialisation.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/serialisation_legacy.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/backwards.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/base.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/check.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/clean.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/forwards.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/new.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/templates/migration.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/tables.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/playground/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/playground/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/playground/commands/run.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/playground/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/commands/new.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/commands/templates/piccolo_conf.py.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/exceptions.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/generate.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/graph.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/templates/graphviz.dot.jinja +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/shell/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/shell/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/shell/commands/run.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/shell/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/sql_shell/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/sql_shell/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/sql_shell/commands/run.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/sql_shell/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/tester/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/tester/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/tester/commands/run.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/tester/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/commands/change_password.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/commands/change_permissions.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/commands/create.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_migrations/2019-11-14T21-52-21.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_migrations/2020-06-11T21-38-55.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_migrations/2021-04-30T16-14-15.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_migrations/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/tables.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/base.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/choices.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/column_types.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/combination.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/base.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/date.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/interval.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/time.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/timestamp.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/timestamptz.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/uuid.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/indexes.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/base.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/comparison.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/math.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/string.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/readable.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/reference.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/conf/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/conf/apps.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/custom_types.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/base.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/cockroach.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/exceptions.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/finder.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/postgres.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/sqlite.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/main.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/py.typed +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/base.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/alter.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/create.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/create_index.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/delete.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/drop_index.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/exists.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/indexes.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/insert.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/objects.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/raw.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/refresh.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/table_exists.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/update.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/mixins.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/proxy.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/querystring.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/schema.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/table_reflection.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/testing/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/testing/model_builder.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/testing/random_builder.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/dictionary.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/encoding.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/graphlib/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/graphlib/_graphlib.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/lazy_loader.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/list.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/naming.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/objects.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/printing.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/pydantic.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/repr.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/sql_values.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/sync.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/warnings.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/dependency_links.txt +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/entry_points.txt +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/requires.txt +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/top_level.txt +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/profiling/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/profiling/run_profile.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/pyproject.toml +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/setup.cfg +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/setup.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/app/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/app/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/app/commands/test_new.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/app/commands/test_show_all.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/asgi/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/asgi/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/asgi/commands/test_new.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/fixtures/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/fixtures/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/fixtures/commands/test_shared.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/meta/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/meta/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/meta/commands/test_version.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/integration/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_diffable_table.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_migration_manager.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_schema_differ.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_schema_snapshot.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_serialisation.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_base.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_check.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_clean.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_forwards_backwards.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_migrations/2020-03-31T20-38-22.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_migrations/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_new.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/test_migration.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/project/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/project/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/project/commands/test_new.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/schema/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/shell/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/shell/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/shell/commands/test_run.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/sql_shell/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/sql_shell/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/sql_shell/commands/test_run.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/tester/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/commands/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/commands/test_change_password.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/commands/test_change_permissions.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/commands/test_create.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/test_tables.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/__init__.py +0 -0
- {piccolo-0.113.0/tests/conf → piccolo-0.115.0/tests/columns/m2m}/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_array.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_base.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_bigint.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_boolean.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_bytea.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_choices.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_combination.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_date.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_db_column_name.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_defaults.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_double_precision.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_interval.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_json.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_jsonb.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_numeric.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_primary_key.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_readable.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_real.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_reference.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_reserved_column_names.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_smallint.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_time.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_timestamp.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_timestamptz.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_uuid.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_varchar.py +0 -0
- {piccolo-0.113.0/tests/engine → piccolo-0.115.0/tests/conf}/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/conf/example.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/conf/test_apps.py +0 -0
- {piccolo-0.113.0/tests/example_apps → piccolo-0.115.0/tests/engine}/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_extra_nodes.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_logging.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_nested_transaction.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_pool.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_transaction.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_version_parsing.py +0 -0
- {piccolo-0.113.0/tests/example_apps/mega → piccolo-0.115.0/tests/example_apps}/__init__.py +0 -0
- {piccolo-0.113.0/tests/example_apps/mega/piccolo_migrations → piccolo-0.115.0/tests/example_apps/mega}/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/mega/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py +0 -0
- {piccolo-0.113.0/tests/example_apps/music → piccolo-0.115.0/tests/example_apps/mega/piccolo_migrations}/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/mega/tables.py +0 -0
- {piccolo-0.113.0/tests/query → piccolo-0.115.0/tests/example_apps/music}/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/music/piccolo_app.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/music/tables.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/music/tables_detailed.py +0 -0
- {piccolo-0.113.0/tests/query/mixins → piccolo-0.115.0/tests/query}/__init__.py +0 -0
- {piccolo-0.113.0/tests/table → piccolo-0.115.0/tests/query/mixins}/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/mixins/test_columns_delegate.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/mixins/test_order_by_delegate.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_await.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_camelcase.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_freeze.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_gather.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_querystring.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_slots.py +0 -0
- {piccolo-0.113.0/tests/table/instance → piccolo-0.115.0/tests/table}/__init__.py +0 -0
- {piccolo-0.113.0/tests/testing → piccolo-0.115.0/tests/table/instance}/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_create.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_get_related.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_get_related_readable.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_instantiate.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_remove.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_save.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_to_dict.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_all_columns.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_alter.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_batch.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_callback.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_constructor.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_create.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_create_db_tables.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_create_table_class.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_delete.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_drop_db_tables.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_exists.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_from_dict.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_indexes.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_inheritance.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_insert.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_join.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_join_on.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_metaclass.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_output.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_raw.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_ref.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_refresh.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_repr.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_select.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_str.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_table_exists.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_update.py +0 -0
- {piccolo-0.113.0/tests/utils → piccolo-0.115.0/tests/testing}/__init__.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/testing/test_model_builder.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/testing/test_random_builder.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_dictionary.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_encoding.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_lazy_loader.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_list.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_naming.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_printing.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_pydantic.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_sql_values.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_sync.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_table_reflection.py +0 -0
- {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_warnings.py +0 -0
@@ -0,0 +1 @@
|
|
1
|
+
__VERSION__ = "0.115.0"
|
@@ -1,19 +1,27 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
+
import sys
|
3
4
|
import typing as t
|
4
5
|
|
6
|
+
import typing_extensions
|
7
|
+
|
5
8
|
from piccolo.apps.fixtures.commands.shared import (
|
6
9
|
FixtureConfig,
|
7
10
|
create_pydantic_fixture_model,
|
8
11
|
)
|
9
12
|
from piccolo.conf.apps import Finder
|
10
13
|
from piccolo.engine import engine_finder
|
14
|
+
from piccolo.query.mixins import OnConflictAction
|
11
15
|
from piccolo.table import Table, sort_table_classes
|
12
16
|
from piccolo.utils.encoding import load_json
|
13
17
|
from piccolo.utils.list import batch
|
14
18
|
|
15
19
|
|
16
|
-
async def load_json_string(
|
20
|
+
async def load_json_string(
|
21
|
+
json_string: str,
|
22
|
+
chunk_size: int = 1000,
|
23
|
+
on_conflict_action: t.Optional[OnConflictAction] = None,
|
24
|
+
):
|
17
25
|
"""
|
18
26
|
Parses the JSON string, and inserts the parsed data into the database.
|
19
27
|
"""
|
@@ -71,10 +79,23 @@ async def load_json_string(json_string: str, chunk_size: int = 1000):
|
|
71
79
|
rows = data[table_class]
|
72
80
|
|
73
81
|
for chunk in batch(data=rows, chunk_size=chunk_size):
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
82
|
+
query = table_class.insert(*chunk)
|
83
|
+
if on_conflict_action is not None:
|
84
|
+
query = query.on_conflict(
|
85
|
+
target=table_class._meta.primary_key,
|
86
|
+
action=on_conflict_action,
|
87
|
+
values=table_class._meta.columns,
|
88
|
+
)
|
89
|
+
await query.run()
|
90
|
+
|
91
|
+
|
92
|
+
async def load(
|
93
|
+
path: str = "fixture.json",
|
94
|
+
chunk_size: int = 1000,
|
95
|
+
on_conflict: t.Optional[
|
96
|
+
typing_extensions.Literal["DO NOTHING", "DO UPDATE"]
|
97
|
+
] = None,
|
98
|
+
):
|
78
99
|
"""
|
79
100
|
Reads the fixture file, and loads the contents into the database.
|
80
101
|
|
@@ -86,8 +107,28 @@ async def load(path: str = "fixture.json", chunk_size: int = 1000):
|
|
86
107
|
determined by the database adapter, which has a max number of
|
87
108
|
parameters per query.
|
88
109
|
|
110
|
+
:param on_conflict:
|
111
|
+
If specified, the fixture will be upserted, meaning that if a row
|
112
|
+
already exists with a matching primary key, then it will be overridden
|
113
|
+
if "DO UPDATE", or it will be ignored if "DO NOTHING".
|
114
|
+
|
89
115
|
"""
|
90
116
|
with open(path, "r") as f:
|
91
117
|
contents = f.read()
|
92
118
|
|
93
|
-
|
119
|
+
on_conflict_action: t.Optional[OnConflictAction] = None
|
120
|
+
|
121
|
+
if on_conflict:
|
122
|
+
try:
|
123
|
+
on_conflict_action = OnConflictAction(on_conflict.upper())
|
124
|
+
except ValueError:
|
125
|
+
sys.exit(
|
126
|
+
f"{on_conflict} isn't a valid option - use 'DO NOTHING' or "
|
127
|
+
"'DO UPDATE'."
|
128
|
+
)
|
129
|
+
|
130
|
+
await load_json_string(
|
131
|
+
contents,
|
132
|
+
chunk_size=chunk_size,
|
133
|
+
on_conflict_action=on_conflict_action,
|
134
|
+
)
|
@@ -826,7 +826,7 @@ class MigrationManager:
|
|
826
826
|
await self._run_query(
|
827
827
|
schema_manager.move_table(
|
828
828
|
table_name=change_table_schema.tablename,
|
829
|
-
new_schema=change_table_schema.new_schema,
|
829
|
+
new_schema=change_table_schema.new_schema or "public",
|
830
830
|
current_schema=change_table_schema.old_schema,
|
831
831
|
)
|
832
832
|
)
|
@@ -57,30 +57,34 @@ class M2MSelect(Selectable):
|
|
57
57
|
)
|
58
58
|
|
59
59
|
def get_select_string(self, engine_type: str, with_alias=True) -> str:
|
60
|
-
|
60
|
+
m2m_table_name_with_schema = (
|
61
|
+
self.m2m._meta.resolved_joining_table._meta.get_formatted_tablename() # noqa: E501
|
62
|
+
) # noqa: E501
|
61
63
|
m2m_relationship_name = self.m2m._meta.name
|
62
64
|
|
63
65
|
fk_1 = self.m2m._meta.primary_foreign_key
|
64
66
|
fk_1_name = fk_1._meta.db_column_name
|
65
67
|
table_1 = fk_1._foreign_key_meta.resolved_references
|
66
68
|
table_1_name = table_1._meta.tablename
|
69
|
+
table_1_name_with_schema = table_1._meta.get_formatted_tablename()
|
67
70
|
table_1_pk_name = table_1._meta.primary_key._meta.db_column_name
|
68
71
|
|
69
72
|
fk_2 = self.m2m._meta.secondary_foreign_key
|
70
73
|
fk_2_name = fk_2._meta.db_column_name
|
71
74
|
table_2 = fk_2._foreign_key_meta.resolved_references
|
72
75
|
table_2_name = table_2._meta.tablename
|
76
|
+
table_2_name_with_schema = table_2._meta.get_formatted_tablename()
|
73
77
|
table_2_pk_name = table_2._meta.primary_key._meta.db_column_name
|
74
78
|
|
75
79
|
inner_select = f"""
|
76
|
-
|
77
|
-
JOIN
|
78
|
-
|
80
|
+
{m2m_table_name_with_schema}
|
81
|
+
JOIN {table_1_name_with_schema} "inner_{table_1_name}" ON (
|
82
|
+
{m2m_table_name_with_schema}."{fk_1_name}" = "inner_{table_1_name}"."{table_1_pk_name}"
|
79
83
|
)
|
80
|
-
JOIN
|
81
|
-
|
84
|
+
JOIN {table_2_name_with_schema} "inner_{table_2_name}" ON (
|
85
|
+
{m2m_table_name_with_schema}."{fk_2_name}" = "inner_{table_2_name}"."{table_2_pk_name}"
|
82
86
|
)
|
83
|
-
WHERE
|
87
|
+
WHERE {m2m_table_name_with_schema}."{fk_1_name}" = "{table_1_name}"."{table_1_pk_name}"
|
84
88
|
""" # noqa: E501
|
85
89
|
|
86
90
|
if engine_type in ("postgres", "cockroach"):
|
@@ -4,19 +4,29 @@ import typing as t
|
|
4
4
|
|
5
5
|
from piccolo.custom_types import Combinable
|
6
6
|
from piccolo.query.base import Query
|
7
|
-
from piccolo.query.methods.select import
|
7
|
+
from piccolo.query.methods.select import Count as SelectCount
|
8
8
|
from piccolo.query.mixins import WhereDelegate
|
9
9
|
from piccolo.querystring import QueryString
|
10
10
|
|
11
11
|
if t.TYPE_CHECKING: # pragma: no cover
|
12
|
+
from piccolo.columns import Column
|
12
13
|
from piccolo.table import Table
|
13
14
|
|
14
15
|
|
15
16
|
class Count(Query):
|
16
|
-
__slots__ = ("where_delegate",)
|
17
17
|
|
18
|
-
|
18
|
+
__slots__ = ("where_delegate", "column", "_distinct")
|
19
|
+
|
20
|
+
def __init__(
|
21
|
+
self,
|
22
|
+
table: t.Type[Table],
|
23
|
+
column: t.Optional[Column] = None,
|
24
|
+
distinct: t.Optional[t.Sequence[Column]] = None,
|
25
|
+
**kwargs,
|
26
|
+
):
|
19
27
|
super().__init__(table, **kwargs)
|
28
|
+
self.column = column
|
29
|
+
self._distinct = distinct
|
20
30
|
self.where_delegate = WhereDelegate()
|
21
31
|
|
22
32
|
###########################################################################
|
@@ -26,6 +36,10 @@ class Count(Query):
|
|
26
36
|
self.where_delegate.where(*where)
|
27
37
|
return self
|
28
38
|
|
39
|
+
def distinct(self: Self, columns: t.Optional[t.Sequence[Column]]) -> Self:
|
40
|
+
self._distinct = columns
|
41
|
+
return self
|
42
|
+
|
29
43
|
###########################################################################
|
30
44
|
|
31
45
|
async def response_handler(self, response) -> bool:
|
@@ -33,14 +47,15 @@ class Count(Query):
|
|
33
47
|
|
34
48
|
@property
|
35
49
|
def default_querystrings(self) -> t.Sequence[QueryString]:
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
50
|
+
table: t.Type[Table] = self.table
|
51
|
+
|
52
|
+
query = table.select(
|
53
|
+
SelectCount(column=self.column, distinct=self._distinct)
|
54
|
+
)
|
55
|
+
|
56
|
+
query.where_delegate._where = self.where_delegate._where
|
57
|
+
|
58
|
+
return query.querystrings
|
44
59
|
|
45
60
|
|
46
61
|
Self = t.TypeVar("Self", bound=Count)
|
@@ -99,43 +99,84 @@ class Avg(Selectable):
|
|
99
99
|
|
100
100
|
class Count(Selectable):
|
101
101
|
"""
|
102
|
-
Used in conjunction with the ``group_by``
|
102
|
+
Used in ``Select`` queries, usually in conjunction with the ``group_by``
|
103
|
+
clause::
|
103
104
|
|
104
|
-
|
105
|
-
|
106
|
-
|
105
|
+
>>> await Band.select(
|
106
|
+
... Band.manager.name.as_alias('manager_name'),
|
107
|
+
... Count(alias='band_count')
|
108
|
+
... ).group_by(Band.manager)
|
109
|
+
[{'manager_name': 'Guido', 'count': 1}, ...]
|
107
110
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
# We can use an alias. These two are equivalent:
|
113
|
-
|
114
|
-
await Band.select(
|
115
|
-
Band.name, Count(alias="total")
|
116
|
-
).group_by(Band.name)
|
111
|
+
It can also be used without the ``group_by`` clause (though you may prefer
|
112
|
+
to the :meth:`Table.count <piccolo.table.Table.count>` method instead, as
|
113
|
+
it's more convenient)::
|
117
114
|
|
118
|
-
await Band.select(
|
119
|
-
|
120
|
-
Count().as_alias("total")
|
121
|
-
).group_by(Band.name)
|
115
|
+
>>> await Band.select(Count())
|
116
|
+
[{'count': 3}]
|
122
117
|
|
123
118
|
"""
|
124
119
|
|
125
120
|
def __init__(
|
126
|
-
self,
|
121
|
+
self,
|
122
|
+
column: t.Optional[Column] = None,
|
123
|
+
distinct: t.Optional[t.Sequence[Column]] = None,
|
124
|
+
alias: str = "count",
|
127
125
|
):
|
126
|
+
"""
|
127
|
+
:param column:
|
128
|
+
If specified, the count is for non-null values in that column.
|
129
|
+
:param distinct:
|
130
|
+
If specified, the count is for distinct values in those columns.
|
131
|
+
:param alias:
|
132
|
+
The name of the value in the response::
|
133
|
+
|
134
|
+
# These two are equivalent:
|
135
|
+
|
136
|
+
await Band.select(
|
137
|
+
Band.name, Count(alias="total")
|
138
|
+
).group_by(Band.name)
|
139
|
+
|
140
|
+
await Band.select(
|
141
|
+
Band.name,
|
142
|
+
Count().as_alias("total")
|
143
|
+
).group_by(Band.name)
|
144
|
+
|
145
|
+
"""
|
146
|
+
if distinct and column:
|
147
|
+
raise ValueError("Only specify `column` or `distinct`")
|
148
|
+
|
128
149
|
self.column = column
|
150
|
+
self.distinct = distinct
|
129
151
|
self._alias = alias
|
130
152
|
|
131
153
|
def get_select_string(
|
132
154
|
self, engine_type: str, with_alias: bool = True
|
133
155
|
) -> str:
|
134
|
-
|
135
|
-
|
156
|
+
expression: str
|
157
|
+
|
158
|
+
if self.distinct:
|
159
|
+
if engine_type == "sqlite":
|
160
|
+
# SQLite doesn't allow us to specify multiple columns, so
|
161
|
+
# instead we concatenate the values.
|
162
|
+
column_names = " || ".join(
|
163
|
+
i._meta.get_full_name(with_alias=False)
|
164
|
+
for i in self.distinct
|
165
|
+
)
|
166
|
+
else:
|
167
|
+
column_names = ", ".join(
|
168
|
+
i._meta.get_full_name(with_alias=False)
|
169
|
+
for i in self.distinct
|
170
|
+
)
|
171
|
+
|
172
|
+
expression = f"DISTINCT ({column_names})"
|
136
173
|
else:
|
137
|
-
|
138
|
-
|
174
|
+
if self.column:
|
175
|
+
expression = self.column._meta.get_full_name(with_alias=False)
|
176
|
+
else:
|
177
|
+
expression = "*"
|
178
|
+
|
179
|
+
return f'COUNT({expression}) AS "{self._alias}"'
|
139
180
|
|
140
181
|
|
141
182
|
class Max(Selectable):
|
@@ -737,12 +778,10 @@ class Select(Query[TableInstance, t.List[t.Dict[str, t.Any]]]):
|
|
737
778
|
query = "SELECT"
|
738
779
|
|
739
780
|
distinct = self.distinct_delegate._distinct
|
740
|
-
if distinct:
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
query += "{}"
|
745
|
-
args.append(distinct.querystring)
|
781
|
+
if distinct.on:
|
782
|
+
distinct.validate_on(self.order_by_delegate._order_by)
|
783
|
+
query += "{}"
|
784
|
+
args.append(distinct.querystring)
|
746
785
|
|
747
786
|
query += f" {columns_str} FROM {self.table._meta.get_formatted_tablename()}" # noqa: E501
|
748
787
|
|
@@ -1114,16 +1114,54 @@ class Table(metaclass=TableMetaclass):
|
|
1114
1114
|
return Objects[TableInstance](table=cls, prefetch=prefetch)
|
1115
1115
|
|
1116
1116
|
@classmethod
|
1117
|
-
def count(
|
1118
|
-
|
1119
|
-
|
1117
|
+
def count(
|
1118
|
+
cls,
|
1119
|
+
column: t.Optional[Column] = None,
|
1120
|
+
distinct: t.Optional[t.Sequence[Column]] = None,
|
1121
|
+
) -> Count:
|
1120
1122
|
|
1121
|
-
|
1123
|
+
"""
|
1124
|
+
Count the number of matching rows::
|
1122
1125
|
|
1123
1126
|
await Band.count().where(Band.popularity > 1000)
|
1124
1127
|
|
1128
|
+
:param column:
|
1129
|
+
If specified, just count rows where this column isn't null.
|
1130
|
+
|
1131
|
+
:param distinct:
|
1132
|
+
Counts the number of distinct values for these columns. For
|
1133
|
+
example, if we have a concerts table::
|
1134
|
+
|
1135
|
+
class Concert(Table):
|
1136
|
+
band = Varchar()
|
1137
|
+
start_date = Date()
|
1138
|
+
|
1139
|
+
With this data:
|
1140
|
+
|
1141
|
+
.. table::
|
1142
|
+
:widths: auto
|
1143
|
+
|
1144
|
+
=========== ==========
|
1145
|
+
band start_date
|
1146
|
+
=========== ==========
|
1147
|
+
Pythonistas 2023-01-01
|
1148
|
+
Pythonistas 2023-02-03
|
1149
|
+
Rustaceans 2023-01-01
|
1150
|
+
=========== ==========
|
1151
|
+
|
1152
|
+
Without the ``distinct`` argument, we get the count of all
|
1153
|
+
rows::
|
1154
|
+
|
1155
|
+
>>> await Concert.count()
|
1156
|
+
3
|
1157
|
+
|
1158
|
+
To get the number of unique concert dates::
|
1159
|
+
|
1160
|
+
>>> await Concert.count(distinct=[Concert.start_date])
|
1161
|
+
2
|
1162
|
+
|
1125
1163
|
"""
|
1126
|
-
return Count(table=cls)
|
1164
|
+
return Count(table=cls, column=column, distinct=distinct)
|
1127
1165
|
|
1128
1166
|
@classmethod
|
1129
1167
|
def exists(cls) -> Exists:
|
@@ -254,7 +254,6 @@ tests/columns/test_double_precision.py
|
|
254
254
|
tests/columns/test_interval.py
|
255
255
|
tests/columns/test_json.py
|
256
256
|
tests/columns/test_jsonb.py
|
257
|
-
tests/columns/test_m2m.py
|
258
257
|
tests/columns/test_numeric.py
|
259
258
|
tests/columns/test_primary_key.py
|
260
259
|
tests/columns/test_readable.py
|
@@ -267,6 +266,10 @@ tests/columns/test_timestamp.py
|
|
267
266
|
tests/columns/test_timestamptz.py
|
268
267
|
tests/columns/test_uuid.py
|
269
268
|
tests/columns/test_varchar.py
|
269
|
+
tests/columns/m2m/__init__.py
|
270
|
+
tests/columns/m2m/base.py
|
271
|
+
tests/columns/m2m/test_m2m.py
|
272
|
+
tests/columns/m2m/test_m2m_schema.py
|
270
273
|
tests/conf/__init__.py
|
271
274
|
tests/conf/example.py
|
272
275
|
tests/conf/test_apps.py
|
@@ -1,5 +1,7 @@
|
|
1
1
|
import datetime
|
2
2
|
import decimal
|
3
|
+
import os
|
4
|
+
import tempfile
|
3
5
|
import typing as t
|
4
6
|
import uuid
|
5
7
|
from unittest import TestCase
|
@@ -8,7 +10,7 @@ from piccolo.apps.fixtures.commands.dump import (
|
|
8
10
|
FixtureConfig,
|
9
11
|
dump_to_json_string,
|
10
12
|
)
|
11
|
-
from piccolo.apps.fixtures.commands.load import load_json_string
|
13
|
+
from piccolo.apps.fixtures.commands.load import load, load_json_string
|
12
14
|
from piccolo.utils.sync import run_sync
|
13
15
|
from tests.base import engines_only
|
14
16
|
from tests.example_apps.mega.tables import MegaTable, SmallTable
|
@@ -240,3 +242,39 @@ class TestDumpLoad(TestCase):
|
|
240
242
|
"not_null_col": "hello",
|
241
243
|
},
|
242
244
|
)
|
245
|
+
|
246
|
+
|
247
|
+
class TestOnConflict(TestCase):
|
248
|
+
def setUp(self) -> None:
|
249
|
+
SmallTable.create_table().run_sync()
|
250
|
+
SmallTable({SmallTable.varchar_col: "Test"}).save().run_sync()
|
251
|
+
|
252
|
+
def tearDown(self) -> None:
|
253
|
+
SmallTable.alter().drop_table().run_sync()
|
254
|
+
|
255
|
+
def test_on_conflict(self):
|
256
|
+
temp_dir = tempfile.gettempdir()
|
257
|
+
|
258
|
+
json_file_path = os.path.join(temp_dir, "fixture.json")
|
259
|
+
|
260
|
+
json_string = run_sync(
|
261
|
+
dump_to_json_string(
|
262
|
+
fixture_configs=[
|
263
|
+
FixtureConfig(
|
264
|
+
app_name="mega",
|
265
|
+
table_class_names=["SmallTable"],
|
266
|
+
)
|
267
|
+
]
|
268
|
+
)
|
269
|
+
)
|
270
|
+
|
271
|
+
if os.path.exists(json_file_path):
|
272
|
+
os.unlink(json_file_path)
|
273
|
+
|
274
|
+
with open(json_file_path, "w") as f:
|
275
|
+
f.write(json_string)
|
276
|
+
|
277
|
+
run_sync(load(path=json_file_path, on_conflict="DO NOTHING"))
|
278
|
+
run_sync(load(path=json_file_path, on_conflict="DO UPDATE"))
|
279
|
+
run_sync(load(path=json_file_path, on_conflict="do nothing"))
|
280
|
+
run_sync(load(path=json_file_path, on_conflict="do update"))
|
{piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/integration/test_migrations.py
RENAMED
@@ -1138,9 +1138,10 @@ class TestSchemas(MigrationTestCase):
|
|
1138
1138
|
).run_sync(),
|
1139
1139
|
)
|
1140
1140
|
|
1141
|
-
def
|
1141
|
+
def test_move_table_from_public_schema(self):
|
1142
1142
|
"""
|
1143
|
-
Make sure the auto migrations
|
1143
|
+
Make sure the auto migrations can move a table from the public schema
|
1144
|
+
to a different schema.
|
1144
1145
|
"""
|
1145
1146
|
self._test_migrations(
|
1146
1147
|
table_snapshots=[
|
@@ -1181,6 +1182,37 @@ class TestSchemas(MigrationTestCase):
|
|
1181
1182
|
self.schema_manager.list_schemas().run_sync(),
|
1182
1183
|
)
|
1183
1184
|
|
1185
|
+
def test_move_table_to_public_schema(self):
|
1186
|
+
"""
|
1187
|
+
Make sure the auto migrations can move a table from a schema to the
|
1188
|
+
public schema.
|
1189
|
+
"""
|
1190
|
+
self._test_migrations(
|
1191
|
+
table_snapshots=[
|
1192
|
+
[self.manager_2],
|
1193
|
+
[self.manager_1],
|
1194
|
+
],
|
1195
|
+
)
|
1196
|
+
|
1197
|
+
# Make sure that the table is in the public schema.
|
1198
|
+
self.assertIn(
|
1199
|
+
"manager",
|
1200
|
+
self.schema_manager.list_tables(schema_name="public").run_sync(),
|
1201
|
+
)
|
1202
|
+
|
1203
|
+
#######################################################################
|
1204
|
+
|
1205
|
+
# Reverse the last migration, which should move the table back to the
|
1206
|
+
# non-public schema.
|
1207
|
+
self._run_backwards(migration_id="1")
|
1208
|
+
|
1209
|
+
self.assertIn(
|
1210
|
+
"manager",
|
1211
|
+
self.schema_manager.list_tables(
|
1212
|
+
schema_name=self.new_schema
|
1213
|
+
).run_sync(),
|
1214
|
+
)
|
1215
|
+
|
1184
1216
|
|
1185
1217
|
@engines_only("postgres", "cockroach")
|
1186
1218
|
class TestSameTableName(MigrationTestCase):
|