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.
Files changed (359) hide show
  1. {piccolo-0.113.0 → piccolo-0.115.0}/PKG-INFO +1 -1
  2. piccolo-0.115.0/piccolo/__init__.py +1 -0
  3. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/commands/load.py +47 -6
  4. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/migration_manager.py +1 -1
  5. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/m2m.py +11 -7
  6. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/count.py +26 -11
  7. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/select.py +67 -28
  8. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/table.py +43 -5
  9. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/PKG-INFO +1 -1
  10. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/SOURCES.txt +4 -1
  11. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/fixtures/commands/test_dump_load.py +39 -1
  12. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/integration/test_migrations.py +34 -2
  13. piccolo-0.113.0/tests/columns/test_m2m.py → piccolo-0.115.0/tests/columns/m2m/base.py +55 -426
  14. piccolo-0.115.0/tests/columns/m2m/test_m2m.py +436 -0
  15. piccolo-0.115.0/tests/columns/m2m/test_m2m_schema.py +48 -0
  16. piccolo-0.115.0/tests/table/test_count.py +77 -0
  17. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_objects.py +4 -1
  18. piccolo-0.115.0/tests/utils/__init__.py +0 -0
  19. piccolo-0.113.0/piccolo/__init__.py +0 -1
  20. piccolo-0.113.0/tests/table/test_count.py +0 -11
  21. {piccolo-0.113.0 → piccolo-0.115.0}/README.md +0 -0
  22. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/__init__.py +0 -0
  23. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/__init__.py +0 -0
  24. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/__init__.py +0 -0
  25. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/new.py +0 -0
  26. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/show_all.py +0 -0
  27. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/templates/piccolo_app.py.jinja +0 -0
  28. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/commands/templates/tables.py.jinja +0 -0
  29. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/app/piccolo_app.py +0 -0
  30. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/__init__.py +0 -0
  31. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/__init__.py +0 -0
  32. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/new.py +0 -0
  33. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/README.md.jinja +0 -0
  34. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/_blacksheep_app.py.jinja +0 -0
  35. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/_fastapi_app.py.jinja +0 -0
  36. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/_litestar_app.py.jinja +0 -0
  37. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/_starlette_app.py.jinja +0 -0
  38. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/app.py.jinja +0 -0
  39. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/conftest.py.jinja +0 -0
  40. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/__init__.py.jinja +0 -0
  41. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/_blacksheep_endpoints.py.jinja +0 -0
  42. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/_litestar_endpoints.py.jinja +0 -0
  43. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/_starlette_endpoints.py.jinja +0 -0
  44. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja +0 -0
  45. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_app.py.jinja +0 -0
  46. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_migrations/README.md +0 -0
  47. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/tables.py.jinja +0 -0
  48. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/templates/base.html.jinja_raw +0 -0
  49. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw +0 -0
  50. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/main.py.jinja +0 -0
  51. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf.py.jinja +0 -0
  52. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf_test.py.jinja +0 -0
  53. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/requirements.txt.jinja +0 -0
  54. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/static/favicon.ico +0 -0
  55. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/commands/templates/app/static/main.css +0 -0
  56. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/asgi/piccolo_app.py +0 -0
  57. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/__init__.py +0 -0
  58. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/commands/__init__.py +0 -0
  59. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/commands/dump.py +0 -0
  60. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/commands/shared.py +0 -0
  61. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/fixtures/piccolo_app.py +0 -0
  62. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/meta/__init__.py +0 -0
  63. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/meta/commands/__init__.py +0 -0
  64. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/meta/commands/version.py +0 -0
  65. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/meta/piccolo_app.py +0 -0
  66. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/__init__.py +0 -0
  67. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/__init__.py +0 -0
  68. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/diffable_table.py +0 -0
  69. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/operations.py +0 -0
  70. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/schema_differ.py +0 -0
  71. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/schema_snapshot.py +0 -0
  72. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/serialisation.py +0 -0
  73. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/auto/serialisation_legacy.py +0 -0
  74. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/__init__.py +0 -0
  75. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/backwards.py +0 -0
  76. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/base.py +0 -0
  77. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/check.py +0 -0
  78. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/clean.py +0 -0
  79. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/forwards.py +0 -0
  80. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/new.py +0 -0
  81. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/commands/templates/migration.py.jinja +0 -0
  82. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/piccolo_app.py +0 -0
  83. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/migrations/tables.py +0 -0
  84. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/playground/__init__.py +0 -0
  85. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/playground/commands/__init__.py +0 -0
  86. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/playground/commands/run.py +0 -0
  87. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/playground/piccolo_app.py +0 -0
  88. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/__init__.py +0 -0
  89. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/commands/__init__.py +0 -0
  90. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/commands/new.py +0 -0
  91. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/commands/templates/piccolo_conf.py.jinja +0 -0
  92. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/project/piccolo_app.py +0 -0
  93. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/__init__.py +0 -0
  94. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/__init__.py +0 -0
  95. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/exceptions.py +0 -0
  96. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/generate.py +0 -0
  97. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/graph.py +0 -0
  98. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/commands/templates/graphviz.dot.jinja +0 -0
  99. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/schema/piccolo_app.py +0 -0
  100. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/shell/__init__.py +0 -0
  101. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/shell/commands/__init__.py +0 -0
  102. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/shell/commands/run.py +0 -0
  103. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/shell/piccolo_app.py +0 -0
  104. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/sql_shell/__init__.py +0 -0
  105. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/sql_shell/commands/__init__.py +0 -0
  106. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/sql_shell/commands/run.py +0 -0
  107. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/sql_shell/piccolo_app.py +0 -0
  108. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/tester/__init__.py +0 -0
  109. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/tester/commands/__init__.py +0 -0
  110. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/tester/commands/run.py +0 -0
  111. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/tester/piccolo_app.py +0 -0
  112. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/__init__.py +0 -0
  113. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/commands/__init__.py +0 -0
  114. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/commands/change_password.py +0 -0
  115. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/commands/change_permissions.py +0 -0
  116. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/commands/create.py +0 -0
  117. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_app.py +0 -0
  118. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_migrations/2019-11-14T21-52-21.py +0 -0
  119. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_migrations/2020-06-11T21-38-55.py +0 -0
  120. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_migrations/2021-04-30T16-14-15.py +0 -0
  121. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/piccolo_migrations/__init__.py +0 -0
  122. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/apps/user/tables.py +0 -0
  123. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/__init__.py +0 -0
  124. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/base.py +0 -0
  125. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/choices.py +0 -0
  126. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/column_types.py +0 -0
  127. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/combination.py +0 -0
  128. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/__init__.py +0 -0
  129. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/base.py +0 -0
  130. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/date.py +0 -0
  131. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/interval.py +0 -0
  132. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/time.py +0 -0
  133. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/timestamp.py +0 -0
  134. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/timestamptz.py +0 -0
  135. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/defaults/uuid.py +0 -0
  136. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/indexes.py +0 -0
  137. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/__init__.py +0 -0
  138. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/base.py +0 -0
  139. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/comparison.py +0 -0
  140. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/math.py +0 -0
  141. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/operators/string.py +0 -0
  142. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/readable.py +0 -0
  143. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/columns/reference.py +0 -0
  144. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/conf/__init__.py +0 -0
  145. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/conf/apps.py +0 -0
  146. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/custom_types.py +0 -0
  147. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/__init__.py +0 -0
  148. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/base.py +0 -0
  149. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/cockroach.py +0 -0
  150. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/exceptions.py +0 -0
  151. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/finder.py +0 -0
  152. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/postgres.py +0 -0
  153. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/engine/sqlite.py +0 -0
  154. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/main.py +0 -0
  155. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/py.typed +0 -0
  156. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/__init__.py +0 -0
  157. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/base.py +0 -0
  158. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/__init__.py +0 -0
  159. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/alter.py +0 -0
  160. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/create.py +0 -0
  161. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/create_index.py +0 -0
  162. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/delete.py +0 -0
  163. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/drop_index.py +0 -0
  164. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/exists.py +0 -0
  165. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/indexes.py +0 -0
  166. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/insert.py +0 -0
  167. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/objects.py +0 -0
  168. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/raw.py +0 -0
  169. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/refresh.py +0 -0
  170. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/table_exists.py +0 -0
  171. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/methods/update.py +0 -0
  172. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/mixins.py +0 -0
  173. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/query/proxy.py +0 -0
  174. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/querystring.py +0 -0
  175. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/schema.py +0 -0
  176. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/table_reflection.py +0 -0
  177. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/testing/__init__.py +0 -0
  178. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/testing/model_builder.py +0 -0
  179. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/testing/random_builder.py +0 -0
  180. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/__init__.py +0 -0
  181. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/dictionary.py +0 -0
  182. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/encoding.py +0 -0
  183. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/graphlib/__init__.py +0 -0
  184. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/graphlib/_graphlib.py +0 -0
  185. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/lazy_loader.py +0 -0
  186. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/list.py +0 -0
  187. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/naming.py +0 -0
  188. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/objects.py +0 -0
  189. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/printing.py +0 -0
  190. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/pydantic.py +0 -0
  191. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/repr.py +0 -0
  192. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/sql_values.py +0 -0
  193. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/sync.py +0 -0
  194. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo/utils/warnings.py +0 -0
  195. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/dependency_links.txt +0 -0
  196. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/entry_points.txt +0 -0
  197. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/requires.txt +0 -0
  198. {piccolo-0.113.0 → piccolo-0.115.0}/piccolo.egg-info/top_level.txt +0 -0
  199. {piccolo-0.113.0 → piccolo-0.115.0}/profiling/__init__.py +0 -0
  200. {piccolo-0.113.0 → piccolo-0.115.0}/profiling/run_profile.py +0 -0
  201. {piccolo-0.113.0 → piccolo-0.115.0}/pyproject.toml +0 -0
  202. {piccolo-0.113.0 → piccolo-0.115.0}/setup.cfg +0 -0
  203. {piccolo-0.113.0 → piccolo-0.115.0}/setup.py +0 -0
  204. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/__init__.py +0 -0
  205. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/app/__init__.py +0 -0
  206. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/app/commands/__init__.py +0 -0
  207. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/app/commands/test_new.py +0 -0
  208. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/app/commands/test_show_all.py +0 -0
  209. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/asgi/__init__.py +0 -0
  210. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/asgi/commands/__init__.py +0 -0
  211. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/asgi/commands/test_new.py +0 -0
  212. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/fixtures/__init__.py +0 -0
  213. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/fixtures/commands/__init__.py +0 -0
  214. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/fixtures/commands/test_shared.py +0 -0
  215. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/meta/__init__.py +0 -0
  216. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/meta/commands/__init__.py +0 -0
  217. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/meta/commands/test_version.py +0 -0
  218. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/__init__.py +0 -0
  219. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/__init__.py +0 -0
  220. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/integration/__init__.py +0 -0
  221. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_diffable_table.py +0 -0
  222. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_migration_manager.py +0 -0
  223. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_schema_differ.py +0 -0
  224. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_schema_snapshot.py +0 -0
  225. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/auto/test_serialisation.py +0 -0
  226. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/__init__.py +0 -0
  227. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_base.py +0 -0
  228. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_check.py +0 -0
  229. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_clean.py +0 -0
  230. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_forwards_backwards.py +0 -0
  231. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_migrations/2020-03-31T20-38-22.py +0 -0
  232. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_migrations/__init__.py +0 -0
  233. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/commands/test_new.py +0 -0
  234. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/migrations/test_migration.py +0 -0
  235. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/project/__init__.py +0 -0
  236. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/project/commands/__init__.py +0 -0
  237. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/project/commands/test_new.py +0 -0
  238. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/schema/__init__.py +0 -0
  239. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/shell/__init__.py +0 -0
  240. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/shell/commands/__init__.py +0 -0
  241. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/shell/commands/test_run.py +0 -0
  242. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/sql_shell/__init__.py +0 -0
  243. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/sql_shell/commands/__init__.py +0 -0
  244. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/sql_shell/commands/test_run.py +0 -0
  245. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/tester/__init__.py +0 -0
  246. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/__init__.py +0 -0
  247. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/commands/__init__.py +0 -0
  248. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/commands/test_change_password.py +0 -0
  249. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/commands/test_change_permissions.py +0 -0
  250. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/commands/test_create.py +0 -0
  251. {piccolo-0.113.0 → piccolo-0.115.0}/tests/apps/user/test_tables.py +0 -0
  252. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/__init__.py +0 -0
  253. {piccolo-0.113.0/tests/conf → piccolo-0.115.0/tests/columns/m2m}/__init__.py +0 -0
  254. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_array.py +0 -0
  255. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_base.py +0 -0
  256. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_bigint.py +0 -0
  257. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_boolean.py +0 -0
  258. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_bytea.py +0 -0
  259. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_choices.py +0 -0
  260. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_combination.py +0 -0
  261. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_date.py +0 -0
  262. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_db_column_name.py +0 -0
  263. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_defaults.py +0 -0
  264. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_double_precision.py +0 -0
  265. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_interval.py +0 -0
  266. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_json.py +0 -0
  267. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_jsonb.py +0 -0
  268. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_numeric.py +0 -0
  269. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_primary_key.py +0 -0
  270. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_readable.py +0 -0
  271. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_real.py +0 -0
  272. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_reference.py +0 -0
  273. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_reserved_column_names.py +0 -0
  274. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_smallint.py +0 -0
  275. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_time.py +0 -0
  276. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_timestamp.py +0 -0
  277. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_timestamptz.py +0 -0
  278. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_uuid.py +0 -0
  279. {piccolo-0.113.0 → piccolo-0.115.0}/tests/columns/test_varchar.py +0 -0
  280. {piccolo-0.113.0/tests/engine → piccolo-0.115.0/tests/conf}/__init__.py +0 -0
  281. {piccolo-0.113.0 → piccolo-0.115.0}/tests/conf/example.py +0 -0
  282. {piccolo-0.113.0 → piccolo-0.115.0}/tests/conf/test_apps.py +0 -0
  283. {piccolo-0.113.0/tests/example_apps → piccolo-0.115.0/tests/engine}/__init__.py +0 -0
  284. {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_extra_nodes.py +0 -0
  285. {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_logging.py +0 -0
  286. {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_nested_transaction.py +0 -0
  287. {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_pool.py +0 -0
  288. {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_transaction.py +0 -0
  289. {piccolo-0.113.0 → piccolo-0.115.0}/tests/engine/test_version_parsing.py +0 -0
  290. {piccolo-0.113.0/tests/example_apps/mega → piccolo-0.115.0/tests/example_apps}/__init__.py +0 -0
  291. {piccolo-0.113.0/tests/example_apps/mega/piccolo_migrations → piccolo-0.115.0/tests/example_apps/mega}/__init__.py +0 -0
  292. {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/mega/piccolo_app.py +0 -0
  293. {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py +0 -0
  294. {piccolo-0.113.0/tests/example_apps/music → piccolo-0.115.0/tests/example_apps/mega/piccolo_migrations}/__init__.py +0 -0
  295. {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/mega/tables.py +0 -0
  296. {piccolo-0.113.0/tests/query → piccolo-0.115.0/tests/example_apps/music}/__init__.py +0 -0
  297. {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/music/piccolo_app.py +0 -0
  298. {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/music/tables.py +0 -0
  299. {piccolo-0.113.0 → piccolo-0.115.0}/tests/example_apps/music/tables_detailed.py +0 -0
  300. {piccolo-0.113.0/tests/query/mixins → piccolo-0.115.0/tests/query}/__init__.py +0 -0
  301. {piccolo-0.113.0/tests/table → piccolo-0.115.0/tests/query/mixins}/__init__.py +0 -0
  302. {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/mixins/test_columns_delegate.py +0 -0
  303. {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/mixins/test_order_by_delegate.py +0 -0
  304. {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_await.py +0 -0
  305. {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_camelcase.py +0 -0
  306. {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_freeze.py +0 -0
  307. {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_gather.py +0 -0
  308. {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_querystring.py +0 -0
  309. {piccolo-0.113.0 → piccolo-0.115.0}/tests/query/test_slots.py +0 -0
  310. {piccolo-0.113.0/tests/table/instance → piccolo-0.115.0/tests/table}/__init__.py +0 -0
  311. {piccolo-0.113.0/tests/testing → piccolo-0.115.0/tests/table/instance}/__init__.py +0 -0
  312. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_create.py +0 -0
  313. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_get_related.py +0 -0
  314. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_get_related_readable.py +0 -0
  315. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_instantiate.py +0 -0
  316. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_remove.py +0 -0
  317. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_save.py +0 -0
  318. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/instance/test_to_dict.py +0 -0
  319. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_all_columns.py +0 -0
  320. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_alter.py +0 -0
  321. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_batch.py +0 -0
  322. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_callback.py +0 -0
  323. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_constructor.py +0 -0
  324. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_create.py +0 -0
  325. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_create_db_tables.py +0 -0
  326. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_create_table_class.py +0 -0
  327. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_delete.py +0 -0
  328. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_drop_db_tables.py +0 -0
  329. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_exists.py +0 -0
  330. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_from_dict.py +0 -0
  331. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_indexes.py +0 -0
  332. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_inheritance.py +0 -0
  333. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_insert.py +0 -0
  334. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_join.py +0 -0
  335. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_join_on.py +0 -0
  336. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_metaclass.py +0 -0
  337. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_output.py +0 -0
  338. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_raw.py +0 -0
  339. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_ref.py +0 -0
  340. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_refresh.py +0 -0
  341. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_repr.py +0 -0
  342. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_select.py +0 -0
  343. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_str.py +0 -0
  344. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_table_exists.py +0 -0
  345. {piccolo-0.113.0 → piccolo-0.115.0}/tests/table/test_update.py +0 -0
  346. {piccolo-0.113.0/tests/utils → piccolo-0.115.0/tests/testing}/__init__.py +0 -0
  347. {piccolo-0.113.0 → piccolo-0.115.0}/tests/testing/test_model_builder.py +0 -0
  348. {piccolo-0.113.0 → piccolo-0.115.0}/tests/testing/test_random_builder.py +0 -0
  349. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_dictionary.py +0 -0
  350. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_encoding.py +0 -0
  351. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_lazy_loader.py +0 -0
  352. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_list.py +0 -0
  353. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_naming.py +0 -0
  354. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_printing.py +0 -0
  355. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_pydantic.py +0 -0
  356. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_sql_values.py +0 -0
  357. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_sync.py +0 -0
  358. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_table_reflection.py +0 -0
  359. {piccolo-0.113.0 → piccolo-0.115.0}/tests/utils/test_warnings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: piccolo
3
- Version: 0.113.0
3
+ Version: 0.115.0
4
4
  Summary: A fast, user friendly ORM and query builder which supports asyncio.
5
5
  Home-page: https://github.com/piccolo-orm/piccolo
6
6
  Author: Daniel Townsend
@@ -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(json_string: str, chunk_size: int = 1000):
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
- await table_class.insert(*chunk).run()
75
-
76
-
77
- async def load(path: str = "fixture.json", chunk_size: int = 1000):
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
- await load_json_string(contents, chunk_size=chunk_size)
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
- m2m_table_name = self.m2m._meta.resolved_joining_table._meta.tablename
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
- "{m2m_table_name}"
77
- JOIN "{table_1_name}" "inner_{table_1_name}" ON (
78
- "{m2m_table_name}"."{fk_1_name}" = "inner_{table_1_name}"."{table_1_pk_name}"
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 "{table_2_name}" "inner_{table_2_name}" ON (
81
- "{m2m_table_name}"."{fk_2_name}" = "inner_{table_2_name}"."{table_2_pk_name}"
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 "{m2m_table_name}"."{fk_1_name}" = "{table_1_name}"."{table_1_pk_name}"
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 Select
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
- def __init__(self, table: t.Type[Table], **kwargs):
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
- select = Select(self.table)
37
- select.where_delegate._where = self.where_delegate._where
38
- return [
39
- QueryString(
40
- 'SELECT COUNT(*) AS "count" FROM ({}) AS "subquery"',
41
- select.querystrings[0],
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`` clause in ``Select`` queries.
102
+ Used in ``Select`` queries, usually in conjunction with the ``group_by``
103
+ clause::
103
104
 
104
- If a column is specified, the count is for non-null values in that
105
- column. If no column is specified, the count is for all rows, whether
106
- they have null values or not.
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
- .. code-block:: python
109
-
110
- await Band.select(Band.name, Count()).group_by(Band.name)
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
- Band.name,
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, column: t.Optional[Column] = None, alias: str = "count"
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
- if self.column is None:
135
- column_name = "*"
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
- column_name = self.column._meta.get_full_name(with_alias=False)
138
- return f'COUNT({column_name}) AS "{self._alias}"'
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
- if distinct.on:
742
- distinct.validate_on(self.order_by_delegate._order_by)
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(cls) -> Count:
1118
- """
1119
- Count the number of matching rows.
1117
+ def count(
1118
+ cls,
1119
+ column: t.Optional[Column] = None,
1120
+ distinct: t.Optional[t.Sequence[Column]] = None,
1121
+ ) -> Count:
1120
1122
 
1121
- .. code-block:: python
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:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: piccolo
3
- Version: 0.113.0
3
+ Version: 0.115.0
4
4
  Summary: A fast, user friendly ORM and query builder which supports asyncio.
5
5
  Home-page: https://github.com/piccolo-orm/piccolo
6
6
  Author: Daniel Townsend
@@ -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"))
@@ -1138,9 +1138,10 @@ class TestSchemas(MigrationTestCase):
1138
1138
  ).run_sync(),
1139
1139
  )
1140
1140
 
1141
- def test_move_schemas(self):
1141
+ def test_move_table_from_public_schema(self):
1142
1142
  """
1143
- Make sure the auto migrations detect that a table's schema has changed.
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):