piccolo 1.13.1__tar.gz → 1.15.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 (385) hide show
  1. {piccolo-1.13.1 → piccolo-1.15.0}/PKG-INFO +1 -1
  2. piccolo-1.15.0/piccolo/__init__.py +1 -0
  3. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/tables.py +6 -2
  4. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/base.py +3 -3
  5. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/engine/base.py +7 -0
  6. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/engine/postgres.py +7 -0
  7. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/base.py +6 -17
  8. piccolo-1.15.0/piccolo/query/methods/refresh.py +186 -0
  9. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/select.py +4 -1
  10. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/querystring.py +1 -1
  11. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/table.py +8 -2
  12. piccolo-1.15.0/piccolo/utils/encoding.py +74 -0
  13. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo.egg-info/PKG-INFO +1 -1
  14. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/user/test_tables.py +12 -4
  15. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/m2m/test_m2m.py +7 -0
  16. piccolo-1.15.0/tests/table/test_refresh.py +297 -0
  17. piccolo-1.13.1/piccolo/__init__.py +0 -1
  18. piccolo-1.13.1/piccolo/query/methods/refresh.py +0 -105
  19. piccolo-1.13.1/piccolo/utils/encoding.py +0 -33
  20. piccolo-1.13.1/tests/table/test_refresh.py +0 -87
  21. {piccolo-1.13.1 → piccolo-1.15.0}/LICENSE +0 -0
  22. {piccolo-1.13.1 → piccolo-1.15.0}/README.md +0 -0
  23. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/__init__.py +0 -0
  24. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/app/__init__.py +0 -0
  25. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/app/commands/__init__.py +0 -0
  26. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/app/commands/new.py +0 -0
  27. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/app/commands/show_all.py +0 -0
  28. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/app/commands/templates/piccolo_app.py.jinja +0 -0
  29. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/app/commands/templates/tables.py.jinja +0 -0
  30. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/app/piccolo_app.py +0 -0
  31. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/__init__.py +0 -0
  32. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/__init__.py +0 -0
  33. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/new.py +0 -0
  34. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/README.md.jinja +0 -0
  35. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/_blacksheep_app.py.jinja +0 -0
  36. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/_esmerald_app.py.jinja +0 -0
  37. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/_fastapi_app.py.jinja +0 -0
  38. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/_lilya_app.py.jinja +0 -0
  39. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/_litestar_app.py.jinja +0 -0
  40. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/_starlette_app.py.jinja +0 -0
  41. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/app.py.jinja +0 -0
  42. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/conftest.py.jinja +0 -0
  43. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/__init__.py.jinja +0 -0
  44. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/_blacksheep_endpoints.py.jinja +0 -0
  45. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/_esmerald_endpoints.py.jinja +0 -0
  46. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/_lilya_endpoints.py.jinja +0 -0
  47. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/_litestar_endpoints.py.jinja +0 -0
  48. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/_starlette_endpoints.py.jinja +0 -0
  49. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja +0 -0
  50. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_app.py.jinja +0 -0
  51. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/piccolo_migrations/README.md +0 -0
  52. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/tables.py.jinja +0 -0
  53. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/templates/base.html.jinja_raw +0 -0
  54. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw +0 -0
  55. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/main.py.jinja +0 -0
  56. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf.py.jinja +0 -0
  57. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/piccolo_conf_test.py.jinja +0 -0
  58. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/requirements.txt.jinja +0 -0
  59. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/static/favicon.ico +0 -0
  60. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/commands/templates/app/static/main.css +0 -0
  61. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/asgi/piccolo_app.py +0 -0
  62. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/fixtures/__init__.py +0 -0
  63. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/fixtures/commands/__init__.py +0 -0
  64. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/fixtures/commands/dump.py +0 -0
  65. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/fixtures/commands/load.py +0 -0
  66. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/fixtures/commands/shared.py +0 -0
  67. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/fixtures/piccolo_app.py +0 -0
  68. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/meta/__init__.py +0 -0
  69. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/meta/commands/__init__.py +0 -0
  70. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/meta/commands/version.py +0 -0
  71. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/meta/piccolo_app.py +0 -0
  72. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/__init__.py +0 -0
  73. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/auto/__init__.py +0 -0
  74. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/auto/diffable_table.py +0 -0
  75. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/auto/migration_manager.py +0 -0
  76. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/auto/operations.py +0 -0
  77. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/auto/schema_differ.py +0 -0
  78. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/auto/schema_snapshot.py +0 -0
  79. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/auto/serialisation.py +0 -0
  80. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/auto/serialisation_legacy.py +0 -0
  81. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/commands/__init__.py +0 -0
  82. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/commands/backwards.py +0 -0
  83. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/commands/base.py +0 -0
  84. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/commands/check.py +0 -0
  85. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/commands/clean.py +0 -0
  86. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/commands/forwards.py +0 -0
  87. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/commands/new.py +0 -0
  88. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/commands/templates/migration.py.jinja +0 -0
  89. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/piccolo_app.py +0 -0
  90. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/migrations/tables.py +0 -0
  91. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/playground/__init__.py +0 -0
  92. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/playground/commands/__init__.py +0 -0
  93. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/playground/commands/run.py +0 -0
  94. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/playground/piccolo_app.py +0 -0
  95. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/project/__init__.py +0 -0
  96. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/project/commands/__init__.py +0 -0
  97. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/project/commands/new.py +0 -0
  98. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/project/commands/templates/piccolo_conf.py.jinja +0 -0
  99. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/project/piccolo_app.py +0 -0
  100. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/schema/__init__.py +0 -0
  101. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/schema/commands/__init__.py +0 -0
  102. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/schema/commands/exceptions.py +0 -0
  103. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/schema/commands/generate.py +0 -0
  104. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/schema/commands/graph.py +0 -0
  105. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/schema/commands/templates/graphviz.dot.jinja +0 -0
  106. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/schema/piccolo_app.py +0 -0
  107. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/shell/__init__.py +0 -0
  108. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/shell/commands/__init__.py +0 -0
  109. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/shell/commands/run.py +0 -0
  110. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/shell/piccolo_app.py +0 -0
  111. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/sql_shell/__init__.py +0 -0
  112. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/sql_shell/commands/__init__.py +0 -0
  113. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/sql_shell/commands/run.py +0 -0
  114. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/sql_shell/piccolo_app.py +0 -0
  115. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/tester/__init__.py +0 -0
  116. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/tester/commands/__init__.py +0 -0
  117. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/tester/commands/run.py +0 -0
  118. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/tester/piccolo_app.py +0 -0
  119. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/__init__.py +0 -0
  120. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/commands/__init__.py +0 -0
  121. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/commands/change_password.py +0 -0
  122. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/commands/change_permissions.py +0 -0
  123. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/commands/create.py +0 -0
  124. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/commands/list.py +0 -0
  125. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/piccolo_app.py +0 -0
  126. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/piccolo_migrations/2019-11-14T21-52-21.py +0 -0
  127. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/piccolo_migrations/2020-06-11T21-38-55.py +0 -0
  128. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/piccolo_migrations/2021-04-30T16-14-15.py +0 -0
  129. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/apps/user/piccolo_migrations/__init__.py +0 -0
  130. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/__init__.py +0 -0
  131. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/choices.py +0 -0
  132. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/column_types.py +0 -0
  133. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/combination.py +0 -0
  134. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/defaults/__init__.py +0 -0
  135. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/defaults/base.py +0 -0
  136. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/defaults/date.py +0 -0
  137. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/defaults/interval.py +0 -0
  138. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/defaults/time.py +0 -0
  139. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/defaults/timestamp.py +0 -0
  140. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/defaults/timestamptz.py +0 -0
  141. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/defaults/uuid.py +0 -0
  142. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/indexes.py +0 -0
  143. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/m2m.py +0 -0
  144. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/operators/__init__.py +0 -0
  145. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/operators/base.py +0 -0
  146. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/operators/comparison.py +0 -0
  147. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/operators/math.py +0 -0
  148. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/operators/string.py +0 -0
  149. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/readable.py +0 -0
  150. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/columns/reference.py +0 -0
  151. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/conf/__init__.py +0 -0
  152. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/conf/apps.py +0 -0
  153. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/custom_types.py +0 -0
  154. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/engine/__init__.py +0 -0
  155. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/engine/cockroach.py +0 -0
  156. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/engine/exceptions.py +0 -0
  157. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/engine/finder.py +0 -0
  158. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/engine/sqlite.py +0 -0
  159. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/main.py +0 -0
  160. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/py.typed +0 -0
  161. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/__init__.py +0 -0
  162. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/functions/__init__.py +0 -0
  163. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/functions/aggregate.py +0 -0
  164. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/functions/base.py +0 -0
  165. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/functions/datetime.py +0 -0
  166. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/functions/math.py +0 -0
  167. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/functions/string.py +0 -0
  168. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/functions/type_conversion.py +0 -0
  169. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/__init__.py +0 -0
  170. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/alter.py +0 -0
  171. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/count.py +0 -0
  172. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/create.py +0 -0
  173. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/create_index.py +0 -0
  174. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/delete.py +0 -0
  175. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/drop_index.py +0 -0
  176. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/exists.py +0 -0
  177. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/indexes.py +0 -0
  178. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/insert.py +0 -0
  179. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/objects.py +0 -0
  180. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/raw.py +0 -0
  181. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/table_exists.py +0 -0
  182. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/methods/update.py +0 -0
  183. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/mixins.py +0 -0
  184. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/query/proxy.py +0 -0
  185. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/schema.py +0 -0
  186. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/table_reflection.py +0 -0
  187. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/testing/__init__.py +0 -0
  188. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/testing/model_builder.py +0 -0
  189. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/testing/random_builder.py +0 -0
  190. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/__init__.py +0 -0
  191. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/dictionary.py +0 -0
  192. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/graphlib/__init__.py +0 -0
  193. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/graphlib/_graphlib.py +0 -0
  194. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/lazy_loader.py +0 -0
  195. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/list.py +0 -0
  196. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/naming.py +0 -0
  197. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/objects.py +0 -0
  198. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/printing.py +0 -0
  199. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/pydantic.py +0 -0
  200. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/repr.py +0 -0
  201. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/sql_values.py +0 -0
  202. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/sync.py +0 -0
  203. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo/utils/warnings.py +0 -0
  204. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo.egg-info/SOURCES.txt +0 -0
  205. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo.egg-info/dependency_links.txt +0 -0
  206. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo.egg-info/entry_points.txt +0 -0
  207. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo.egg-info/requires.txt +0 -0
  208. {piccolo-1.13.1 → piccolo-1.15.0}/piccolo.egg-info/top_level.txt +0 -0
  209. {piccolo-1.13.1 → piccolo-1.15.0}/profiling/__init__.py +0 -0
  210. {piccolo-1.13.1 → piccolo-1.15.0}/profiling/run_profile.py +0 -0
  211. {piccolo-1.13.1 → piccolo-1.15.0}/pyproject.toml +0 -0
  212. {piccolo-1.13.1 → piccolo-1.15.0}/setup.cfg +0 -0
  213. {piccolo-1.13.1 → piccolo-1.15.0}/setup.py +0 -0
  214. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/__init__.py +0 -0
  215. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/app/__init__.py +0 -0
  216. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/app/commands/__init__.py +0 -0
  217. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/app/commands/test_new.py +0 -0
  218. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/app/commands/test_show_all.py +0 -0
  219. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/asgi/__init__.py +0 -0
  220. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/asgi/commands/__init__.py +0 -0
  221. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/asgi/commands/test_new.py +0 -0
  222. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/fixtures/__init__.py +0 -0
  223. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/fixtures/commands/__init__.py +0 -0
  224. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/fixtures/commands/test_dump_load.py +0 -0
  225. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/fixtures/commands/test_shared.py +0 -0
  226. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/meta/__init__.py +0 -0
  227. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/meta/commands/__init__.py +0 -0
  228. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/meta/commands/test_version.py +0 -0
  229. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/__init__.py +0 -0
  230. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/auto/__init__.py +0 -0
  231. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/auto/integration/__init__.py +0 -0
  232. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/auto/integration/test_migrations.py +0 -0
  233. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/auto/test_diffable_table.py +0 -0
  234. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/auto/test_migration_manager.py +0 -0
  235. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/auto/test_schema_differ.py +0 -0
  236. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/auto/test_schema_snapshot.py +0 -0
  237. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/auto/test_serialisation.py +0 -0
  238. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/commands/__init__.py +0 -0
  239. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/commands/test_base.py +0 -0
  240. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/commands/test_check.py +0 -0
  241. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/commands/test_clean.py +0 -0
  242. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/commands/test_forwards_backwards.py +0 -0
  243. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/commands/test_migrations/2020-03-31T20-38-22.py +0 -0
  244. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/commands/test_migrations/__init__.py +0 -0
  245. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/commands/test_new.py +0 -0
  246. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/migrations/test_migration.py +0 -0
  247. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/project/__init__.py +0 -0
  248. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/project/commands/__init__.py +0 -0
  249. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/project/commands/test_new.py +0 -0
  250. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/schema/__init__.py +0 -0
  251. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/shell/__init__.py +0 -0
  252. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/shell/commands/__init__.py +0 -0
  253. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/shell/commands/test_run.py +0 -0
  254. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/sql_shell/__init__.py +0 -0
  255. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/sql_shell/commands/__init__.py +0 -0
  256. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/sql_shell/commands/test_run.py +0 -0
  257. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/tester/__init__.py +0 -0
  258. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/user/__init__.py +0 -0
  259. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/user/commands/__init__.py +0 -0
  260. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/user/commands/test_change_password.py +0 -0
  261. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/user/commands/test_change_permissions.py +0 -0
  262. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/user/commands/test_create.py +0 -0
  263. {piccolo-1.13.1 → piccolo-1.15.0}/tests/apps/user/commands/test_list.py +0 -0
  264. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/__init__.py +0 -0
  265. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/m2m/__init__.py +0 -0
  266. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/m2m/base.py +0 -0
  267. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/m2m/test_m2m_schema.py +0 -0
  268. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_array.py +0 -0
  269. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_base.py +0 -0
  270. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_bigint.py +0 -0
  271. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_boolean.py +0 -0
  272. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_bytea.py +0 -0
  273. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_choices.py +0 -0
  274. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_combination.py +0 -0
  275. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_date.py +0 -0
  276. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_db_column_name.py +0 -0
  277. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_defaults.py +0 -0
  278. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_double_precision.py +0 -0
  279. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_get_sql_value.py +0 -0
  280. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_interval.py +0 -0
  281. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_json.py +0 -0
  282. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_jsonb.py +0 -0
  283. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_numeric.py +0 -0
  284. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_primary_key.py +0 -0
  285. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_readable.py +0 -0
  286. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_real.py +0 -0
  287. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_reference.py +0 -0
  288. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_reserved_column_names.py +0 -0
  289. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_smallint.py +0 -0
  290. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_time.py +0 -0
  291. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_timestamp.py +0 -0
  292. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_timestamptz.py +0 -0
  293. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_uuid.py +0 -0
  294. {piccolo-1.13.1 → piccolo-1.15.0}/tests/columns/test_varchar.py +0 -0
  295. {piccolo-1.13.1 → piccolo-1.15.0}/tests/conf/__init__.py +0 -0
  296. {piccolo-1.13.1 → piccolo-1.15.0}/tests/conf/example.py +0 -0
  297. {piccolo-1.13.1 → piccolo-1.15.0}/tests/conf/test_apps.py +0 -0
  298. {piccolo-1.13.1 → piccolo-1.15.0}/tests/engine/__init__.py +0 -0
  299. {piccolo-1.13.1 → piccolo-1.15.0}/tests/engine/test_extra_nodes.py +0 -0
  300. {piccolo-1.13.1 → piccolo-1.15.0}/tests/engine/test_logging.py +0 -0
  301. {piccolo-1.13.1 → piccolo-1.15.0}/tests/engine/test_nested_transaction.py +0 -0
  302. {piccolo-1.13.1 → piccolo-1.15.0}/tests/engine/test_pool.py +0 -0
  303. {piccolo-1.13.1 → piccolo-1.15.0}/tests/engine/test_transaction.py +0 -0
  304. {piccolo-1.13.1 → piccolo-1.15.0}/tests/engine/test_version_parsing.py +0 -0
  305. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/__init__.py +0 -0
  306. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/mega/__init__.py +0 -0
  307. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/mega/piccolo_app.py +0 -0
  308. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py +0 -0
  309. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/mega/piccolo_migrations/__init__.py +0 -0
  310. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/mega/tables.py +0 -0
  311. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/music/__init__.py +0 -0
  312. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/music/piccolo_app.py +0 -0
  313. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/music/tables.py +0 -0
  314. {piccolo-1.13.1 → piccolo-1.15.0}/tests/example_apps/music/tables_detailed.py +0 -0
  315. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/__init__.py +0 -0
  316. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/functions/__init__.py +0 -0
  317. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/functions/base.py +0 -0
  318. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/functions/test_datetime.py +0 -0
  319. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/functions/test_functions.py +0 -0
  320. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/functions/test_math.py +0 -0
  321. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/functions/test_string.py +0 -0
  322. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/functions/test_type_conversion.py +0 -0
  323. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/mixins/__init__.py +0 -0
  324. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/mixins/test_columns_delegate.py +0 -0
  325. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/mixins/test_order_by_delegate.py +0 -0
  326. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/test_await.py +0 -0
  327. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/test_camelcase.py +0 -0
  328. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/test_freeze.py +0 -0
  329. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/test_gather.py +0 -0
  330. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/test_querystring.py +0 -0
  331. {piccolo-1.13.1 → piccolo-1.15.0}/tests/query/test_slots.py +0 -0
  332. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/__init__.py +0 -0
  333. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/instance/__init__.py +0 -0
  334. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/instance/test_create.py +0 -0
  335. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/instance/test_get_related.py +0 -0
  336. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/instance/test_get_related_readable.py +0 -0
  337. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/instance/test_instantiate.py +0 -0
  338. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/instance/test_remove.py +0 -0
  339. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/instance/test_save.py +0 -0
  340. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/instance/test_to_dict.py +0 -0
  341. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_all_columns.py +0 -0
  342. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_alter.py +0 -0
  343. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_batch.py +0 -0
  344. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_callback.py +0 -0
  345. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_constructor.py +0 -0
  346. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_count.py +0 -0
  347. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_create.py +0 -0
  348. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_create_db_tables.py +0 -0
  349. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_create_table_class.py +0 -0
  350. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_delete.py +0 -0
  351. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_drop_db_tables.py +0 -0
  352. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_exists.py +0 -0
  353. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_from_dict.py +0 -0
  354. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_indexes.py +0 -0
  355. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_inheritance.py +0 -0
  356. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_insert.py +0 -0
  357. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_join.py +0 -0
  358. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_join_on.py +0 -0
  359. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_metaclass.py +0 -0
  360. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_objects.py +0 -0
  361. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_output.py +0 -0
  362. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_raw.py +0 -0
  363. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_ref.py +0 -0
  364. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_repr.py +0 -0
  365. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_select.py +0 -0
  366. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_str.py +0 -0
  367. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_table_exists.py +0 -0
  368. {piccolo-1.13.1 → piccolo-1.15.0}/tests/table/test_update.py +0 -0
  369. {piccolo-1.13.1 → piccolo-1.15.0}/tests/test_main.py +0 -0
  370. {piccolo-1.13.1 → piccolo-1.15.0}/tests/test_schema.py +0 -0
  371. {piccolo-1.13.1 → piccolo-1.15.0}/tests/testing/__init__.py +0 -0
  372. {piccolo-1.13.1 → piccolo-1.15.0}/tests/testing/test_model_builder.py +0 -0
  373. {piccolo-1.13.1 → piccolo-1.15.0}/tests/testing/test_random_builder.py +0 -0
  374. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/__init__.py +0 -0
  375. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_dictionary.py +0 -0
  376. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_encoding.py +0 -0
  377. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_lazy_loader.py +0 -0
  378. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_list.py +0 -0
  379. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_naming.py +0 -0
  380. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_printing.py +0 -0
  381. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_pydantic.py +0 -0
  382. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_sql_values.py +0 -0
  383. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_sync.py +0 -0
  384. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_table_reflection.py +0 -0
  385. {piccolo-1.13.1 → piccolo-1.15.0}/tests/utils/test_warnings.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: piccolo
3
- Version: 1.13.1
3
+ Version: 1.15.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__ = "1.15.0"
@@ -91,10 +91,14 @@ class BaseUser(Table, tablename="piccolo_user"):
91
91
  raise ValueError("A password must be provided.")
92
92
 
93
93
  if len(password) < cls._min_password_length:
94
- raise ValueError("The password is too short.")
94
+ raise ValueError(
95
+ f"The password is too short. (min {cls._min_password_length})"
96
+ )
95
97
 
96
98
  if len(password) > cls._max_password_length:
97
- raise ValueError("The password is too long.")
99
+ raise ValueError(
100
+ f"The password is too long. (max {cls._max_password_length})"
101
+ )
98
102
 
99
103
  if password.startswith("pbkdf2_sha256"):
100
104
  logger.warning(
@@ -250,11 +250,11 @@ class ColumnMeta:
250
250
 
251
251
  if self.call_chain:
252
252
  column_name = (
253
- "$".join(
253
+ ".".join(
254
254
  t.cast(str, i._meta.db_column_name)
255
255
  for i in self.call_chain
256
256
  )
257
- + f"${column_name}"
257
+ + f".{column_name}"
258
258
  )
259
259
 
260
260
  return column_name
@@ -291,7 +291,7 @@ class ColumnMeta:
291
291
  'band$manager.name'
292
292
 
293
293
  >>> Band.manager.name._meta.get_full_name(with_alias=True)
294
- 'band$manager.name AS "manager$name"'
294
+ 'band$manager.name AS "manager.name"'
295
295
 
296
296
  :param include_quotes:
297
297
  If you're using the name in a SQL query, each component needs to be
@@ -132,6 +132,13 @@ class Engine(t.Generic[TransactionClass], metaclass=ABCMeta):
132
132
  ):
133
133
  pass
134
134
 
135
+ def transform_response_to_dicts(self, results) -> t.List[t.Dict]:
136
+ """
137
+ If the database adapter returns something other than a list of
138
+ dictionaries, it should perform the transformation here.
139
+ """
140
+ return results
141
+
135
142
  @abstractmethod
136
143
  async def run_ddl(self, ddl: str, in_pool: bool = True):
137
144
  pass
@@ -579,6 +579,13 @@ class PostgresEngine(Engine[PostgresTransaction]):
579
579
 
580
580
  return response
581
581
 
582
+ def transform_response_to_dicts(self, results) -> t.List[t.Dict]:
583
+ """
584
+ asyncpg returns a special Record object, so we need to convert it to
585
+ a dict.
586
+ """
587
+ return [dict(i) for i in results]
588
+
582
589
  def atomic(self) -> Atomic:
583
590
  return Atomic(engine=self)
584
591
 
@@ -45,20 +45,11 @@ class Query(t.Generic[TableInstance, QueryResponseType]):
45
45
  raise ValueError("Engine isn't defined.")
46
46
 
47
47
  async def _process_results(self, results) -> QueryResponseType:
48
- if results:
49
- keys = results[0].keys()
50
- keys = [i.replace("$", ".") for i in keys]
51
- if self.engine_type in ("postgres", "cockroach"):
52
- # asyncpg returns a special Record object. We can pass it
53
- # directly into zip without calling `values` on it. This can
54
- # save us hundreds of microseconds, depending on the number of
55
- # results.
56
- raw = [dict(zip(keys, i)) for i in results]
57
- else:
58
- # SQLite returns a list of dictionaries.
59
- raw = [dict(zip(keys, i.values())) for i in results]
60
- else:
61
- raw = []
48
+ raw = (
49
+ self.table._meta.db.transform_response_to_dicts(results)
50
+ if results
51
+ else []
52
+ )
62
53
 
63
54
  if hasattr(self, "_raw_response_callback"):
64
55
  self._raw_response_callback(raw)
@@ -88,9 +79,7 @@ class Query(t.Generic[TableInstance, QueryResponseType]):
88
79
  if column._alias is not None:
89
80
  json_column_names.append(column._alias)
90
81
  elif len(column._meta.call_chain) > 0:
91
- json_column_names.append(
92
- column._meta.get_default_alias().replace("$", ".")
93
- )
82
+ json_column_names.append(column._meta.get_default_alias())
94
83
  else:
95
84
  json_column_names.append(column._meta.name)
96
85
 
@@ -0,0 +1,186 @@
1
+ from __future__ import annotations
2
+
3
+ import typing as t
4
+
5
+ from piccolo.utils.encoding import JSONDict
6
+ from piccolo.utils.sync import run_sync
7
+
8
+ if t.TYPE_CHECKING: # pragma: no cover
9
+ from piccolo.columns import Column
10
+ from piccolo.table import Table
11
+
12
+
13
+ class Refresh:
14
+ """
15
+ Used to refresh :class:`Table <piccolo.table.Table>` instances with the
16
+ latest data data from the database. Accessible via
17
+ :meth:`refresh <piccolo.table.Table.refresh>`.
18
+
19
+ :param instance:
20
+ The instance to refresh.
21
+ :param columns:
22
+ Which columns to refresh - it not specified, then all columns are
23
+ refreshed.
24
+ :param load_json:
25
+ Whether to load ``JSON`` / ``JSONB`` columns as objects, instead of
26
+ just a string.
27
+
28
+ """
29
+
30
+ def __init__(
31
+ self,
32
+ instance: Table,
33
+ columns: t.Optional[t.Sequence[Column]] = None,
34
+ load_json: bool = False,
35
+ ):
36
+ self.instance = instance
37
+
38
+ if columns:
39
+ for column in columns:
40
+ if len(column._meta.call_chain) > 0:
41
+ raise ValueError(
42
+ "We can't currently selectively refresh certain "
43
+ "columns on child objects (e.g. Concert.band_1.name). "
44
+ "Please just specify top level columns (e.g. "
45
+ "Concert.band_1), and the entire child object will be "
46
+ "refreshed."
47
+ )
48
+
49
+ self.columns = columns
50
+ self.load_json = load_json
51
+
52
+ @property
53
+ def _columns(self) -> t.Sequence[Column]:
54
+ """
55
+ Works out which columns the user wants to refresh.
56
+ """
57
+ if self.columns:
58
+ return self.columns
59
+
60
+ return [
61
+ i for i in self.instance._meta.columns if not i._meta.primary_key
62
+ ]
63
+
64
+ def _get_columns(self, instance: Table, columns: t.Sequence[Column]):
65
+ """
66
+ If `prefetch` was used on the object, for example::
67
+
68
+ >>> await Band.objects(Band.manager)
69
+
70
+ We should also update the prefetched object.
71
+
72
+ It works multiple level deep. If we refresh this::
73
+
74
+ >>> await Album.objects(Album.band.manager).first()
75
+
76
+ It will update the nested `band` object, and also the `manager`
77
+ object.
78
+
79
+ """
80
+ from piccolo.columns.column_types import ForeignKey
81
+ from piccolo.table import Table
82
+
83
+ select_columns = []
84
+
85
+ for column in columns:
86
+ if isinstance(column, ForeignKey) and isinstance(
87
+ (child_instance := getattr(instance, column._meta.name)),
88
+ Table,
89
+ ):
90
+ select_columns.extend(
91
+ self._get_columns(
92
+ child_instance,
93
+ # Fetch all columns (even the primary key, just in
94
+ # case the foreign key now references a different row).
95
+ column.all_columns(),
96
+ )
97
+ )
98
+ else:
99
+ select_columns.append(column)
100
+
101
+ return select_columns
102
+
103
+ def _update_instance(self, instance: Table, data_dict: t.Dict):
104
+ """
105
+ Update the table instance. It is called recursively, if the instance
106
+ has child instances.
107
+ """
108
+ for key, value in data_dict.items():
109
+ if isinstance(value, dict) and not isinstance(value, JSONDict):
110
+ # If the value is a dict, then it's a child instance.
111
+ if all(i is None for i in value.values()):
112
+ # If all values in the nested object are None, then we can
113
+ # safely assume that the object itself is null, as the
114
+ # primary key value must be null.
115
+ setattr(instance, key, None)
116
+ else:
117
+ self._update_instance(getattr(instance, key), value)
118
+ else:
119
+ setattr(instance, key, value)
120
+
121
+ async def run(
122
+ self, in_pool: bool = True, node: t.Optional[str] = None
123
+ ) -> Table:
124
+ """
125
+ Run it asynchronously. For example::
126
+
127
+ await my_instance.refresh().run()
128
+
129
+ # or for convenience:
130
+ await my_instance.refresh()
131
+
132
+ Modifies the instance in place, but also returns it as a convenience.
133
+
134
+ """
135
+ instance = self.instance
136
+
137
+ if not instance._exists_in_db:
138
+ raise ValueError("The instance doesn't exist in the database.")
139
+
140
+ pk_column = instance._meta.primary_key
141
+
142
+ primary_key_value = getattr(instance, pk_column._meta.name, None)
143
+
144
+ if primary_key_value is None:
145
+ raise ValueError("The instance's primary key value isn't defined.")
146
+
147
+ columns = self._columns
148
+ if not columns:
149
+ raise ValueError("No columns to fetch.")
150
+
151
+ select_columns = self._get_columns(
152
+ instance=self.instance, columns=columns
153
+ )
154
+
155
+ data_dict = (
156
+ await instance.__class__.select(*select_columns)
157
+ .where(pk_column == primary_key_value)
158
+ .output(nested=True, load_json=self.load_json)
159
+ .first()
160
+ .run(node=node, in_pool=in_pool)
161
+ )
162
+
163
+ if data_dict is None:
164
+ raise ValueError(
165
+ "The object doesn't exist in the database any more."
166
+ )
167
+
168
+ self._update_instance(instance=instance, data_dict=data_dict)
169
+
170
+ return instance
171
+
172
+ def __await__(self):
173
+ """
174
+ If the user doesn't explicity call :meth:`run`, proxy to it as a
175
+ convenience.
176
+ """
177
+ return self.run().__await__()
178
+
179
+ def run_sync(self, *args, **kwargs) -> Table:
180
+ """
181
+ Run it synchronously. For example::
182
+
183
+ my_instance.refresh().run_sync()
184
+
185
+ """
186
+ return run_sync(self.run(*args, **kwargs))
@@ -406,6 +406,9 @@ class Select(Query[TableInstance, t.List[t.Dict[str, t.Any]]]):
406
406
  def output(self: Self, *, load_json: bool, as_list: bool) -> SelectJSON: # type: ignore # noqa: E501
407
407
  ...
408
408
 
409
+ @t.overload
410
+ def output(self: Self, *, load_json: bool, nested: bool) -> Self: ...
411
+
409
412
  @t.overload
410
413
  def output(self: Self, *, nested: bool) -> Self: ...
411
414
 
@@ -574,7 +577,7 @@ class Select(Query[TableInstance, t.List[t.Dict[str, t.Any]]]):
574
577
  query += "{}"
575
578
  args.append(distinct.querystring)
576
579
 
577
- columns_str = ", ".join("{}" for i in select_strings)
580
+ columns_str = ", ".join("{}" for _ in select_strings)
578
581
  query += f" {columns_str} FROM {self.table._meta.get_formatted_tablename()}" # noqa: E501
579
582
  args.extend(select_strings)
580
583
 
@@ -246,7 +246,7 @@ class QueryString(Selectable):
246
246
  self, engine_type: str, with_alias: bool = True
247
247
  ) -> QueryString:
248
248
  if with_alias and self._alias:
249
- return QueryString("{} AS " + self._alias, self)
249
+ return QueryString("{} AS " + f'"{self._alias}"', self)
250
250
  else:
251
251
  return self
252
252
 
@@ -541,7 +541,9 @@ class Table(metaclass=TableMetaclass):
541
541
  )
542
542
 
543
543
  def refresh(
544
- self, columns: t.Optional[t.Sequence[Column]] = None
544
+ self,
545
+ columns: t.Optional[t.Sequence[Column]] = None,
546
+ load_json: bool = False,
545
547
  ) -> Refresh:
546
548
  """
547
549
  Used to fetch the latest data for this instance from the database.
@@ -551,6 +553,10 @@ class Table(metaclass=TableMetaclass):
551
553
  If you only want to refresh certain columns, specify them here.
552
554
  Otherwise all columns are refreshed.
553
555
 
556
+ :param load_json:
557
+ Whether to load ``JSON`` / ``JSONB`` columns as objects, instead of
558
+ just a string.
559
+
554
560
  Example usage::
555
561
 
556
562
  # Get an instance from the database.
@@ -564,7 +570,7 @@ class Table(metaclass=TableMetaclass):
564
570
  instance.refresh().run_sync()
565
571
 
566
572
  """
567
- return Refresh(instance=self, columns=columns)
573
+ return Refresh(instance=self, columns=columns, load_json=load_json)
568
574
 
569
575
  @t.overload
570
576
  def get_related(
@@ -0,0 +1,74 @@
1
+ from __future__ import annotations
2
+
3
+ import typing as t
4
+
5
+ try:
6
+ import orjson
7
+
8
+ ORJSON = True
9
+ except ImportError:
10
+ import json
11
+
12
+ ORJSON = False
13
+
14
+
15
+ def dump_json(data: t.Any, pretty: bool = False) -> str:
16
+ if ORJSON:
17
+ orjson_params: t.Dict[str, t.Any] = {"default": str}
18
+ if pretty:
19
+ orjson_params["option"] = (
20
+ orjson.OPT_INDENT_2 | orjson.OPT_APPEND_NEWLINE # type: ignore
21
+ )
22
+ return orjson.dumps(data, **orjson_params).decode( # type: ignore
23
+ "utf8"
24
+ )
25
+ else:
26
+ params: t.Dict[str, t.Any] = {"default": str}
27
+ if pretty:
28
+ params["indent"] = 2
29
+ return json.dumps(data, **params) # type: ignore
30
+
31
+
32
+ class JSONDict(dict):
33
+ """
34
+ Once we have parsed a JSON string into a dictionary, we can't distinguish
35
+ it from other dictionaries.
36
+
37
+ Sometimes we might want to - for example::
38
+
39
+ >>> await Album.select(
40
+ ... Album.all_columns(),
41
+ ... Album.recording_studio.all_columns()
42
+ ... ).output(
43
+ ... nested=True,
44
+ ... load_json=True
45
+ ... )
46
+
47
+ [{
48
+ 'id': 1,
49
+ 'band': 1,
50
+ 'name': 'Awesome album 1',
51
+ 'recorded_at': {
52
+ 'id': 1,
53
+ 'facilities': {'restaurant': True, 'mixing_desk': True},
54
+ 'name': 'Abbey Road'
55
+ },
56
+ 'release_date': datetime.date(2021, 1, 1)
57
+ }]
58
+
59
+ Facilities could be mistaken for a table.
60
+
61
+ """
62
+
63
+ ...
64
+
65
+
66
+ def load_json(data: str) -> t.Any:
67
+ response = (
68
+ orjson.loads(data) if ORJSON else json.loads(data) # type: ignore
69
+ )
70
+
71
+ if isinstance(response, dict):
72
+ return JSONDict(**response)
73
+
74
+ return response
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: piccolo
3
- Version: 1.13.1
3
+ Version: 1.15.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
@@ -109,7 +109,7 @@ class TestLogin(TestCase):
109
109
  BaseUser.update_password_sync(username, malicious_password)
110
110
  self.assertEqual(
111
111
  manager.exception.__str__(),
112
- "The password is too long.",
112
+ f"The password is too long. (max {BaseUser._max_password_length})",
113
113
  )
114
114
 
115
115
  # Test short passwords
@@ -118,7 +118,10 @@ class TestLogin(TestCase):
118
118
  BaseUser.update_password_sync(username, short_password)
119
119
  self.assertEqual(
120
120
  manager.exception.__str__(),
121
- "The password is too short.",
121
+ (
122
+ "The password is too short. (min "
123
+ f"{BaseUser._min_password_length})"
124
+ ),
122
125
  )
123
126
 
124
127
  # Test no password
@@ -205,7 +208,11 @@ class TestCreateUser(TestCase):
205
208
  BaseUser.create_user_sync(username="bob", password="abc")
206
209
 
207
210
  self.assertEqual(
208
- manager.exception.__str__(), "The password is too short."
211
+ manager.exception.__str__(),
212
+ (
213
+ "The password is too short. (min "
214
+ f"{BaseUser._min_password_length})"
215
+ ),
209
216
  )
210
217
 
211
218
  def test_long_password_error(self):
@@ -216,7 +223,8 @@ class TestCreateUser(TestCase):
216
223
  )
217
224
 
218
225
  self.assertEqual(
219
- manager.exception.__str__(), "The password is too long."
226
+ manager.exception.__str__(),
227
+ f"The password is too long. (max {BaseUser._max_password_length})",
220
228
  )
221
229
 
222
230
  def test_no_username_error(self):
@@ -4,6 +4,7 @@ import decimal
4
4
  import uuid
5
5
  from unittest import TestCase
6
6
 
7
+ from piccolo.utils.encoding import JSONDict
7
8
  from tests.base import engines_skip
8
9
 
9
10
  try:
@@ -376,6 +377,9 @@ class TestM2MComplexSchema(TestCase):
376
377
 
377
378
  if isinstance(column, UUID):
378
379
  self.assertIn(type(returned_value), (uuid.UUID, asyncpgUUID))
380
+ elif isinstance(column, (JSON, JSONB)):
381
+ self.assertEqual(type(returned_value), JSONDict)
382
+ self.assertEqual(original_value, returned_value)
379
383
  else:
380
384
  self.assertEqual(
381
385
  type(original_value),
@@ -401,6 +405,9 @@ class TestM2MComplexSchema(TestCase):
401
405
  if isinstance(column, UUID):
402
406
  self.assertIn(type(returned_value), (uuid.UUID, asyncpgUUID))
403
407
  self.assertEqual(str(original_value), str(returned_value))
408
+ elif isinstance(column, (JSON, JSONB)):
409
+ self.assertEqual(type(returned_value), JSONDict)
410
+ self.assertEqual(original_value, returned_value)
404
411
  else:
405
412
  self.assertEqual(
406
413
  type(original_value),