piccolo 1.22.0__py3-none-any.whl → 1.24.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- piccolo/__init__.py +1 -1
- piccolo/apps/asgi/commands/new.py +3 -0
- piccolo/apps/asgi/commands/templates/app/_falcon_app.py.jinja +60 -0
- piccolo/apps/asgi/commands/templates/app/_quart_app.py.jinja +119 -0
- piccolo/apps/asgi/commands/templates/app/_sanic_app.py.jinja +121 -0
- piccolo/apps/asgi/commands/templates/app/app.py.jinja +6 -0
- piccolo/apps/asgi/commands/templates/app/home/_falcon_endpoints.py.jinja +19 -0
- piccolo/apps/asgi/commands/templates/app/home/_quart_endpoints.py.jinja +18 -0
- piccolo/apps/asgi/commands/templates/app/home/_sanic_endpoints.py.jinja +17 -0
- piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja +6 -0
- piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw +15 -0
- piccolo/apps/sql_shell/commands/run.py +13 -14
- piccolo/apps/user/tables.py +3 -1
- piccolo/columns/column_types.py +1 -1
- piccolo/columns/defaults/timestamptz.py +1 -0
- piccolo/engine/sqlite.py +14 -2
- piccolo/query/methods/objects.py +5 -7
- {piccolo-1.22.0.dist-info → piccolo-1.24.0.dist-info}/METADATA +32 -23
- {piccolo-1.22.0.dist-info → piccolo-1.24.0.dist-info}/RECORD +27 -20
- {piccolo-1.22.0.dist-info → piccolo-1.24.0.dist-info}/WHEEL +1 -1
- {piccolo-1.22.0.dist-info → piccolo-1.24.0.dist-info}/entry_points.txt +0 -1
- tests/apps/sql_shell/commands/test_run.py +26 -2
- tests/columns/test_integer.py +32 -0
- tests/table/test_insert.py +1 -1
- tests/table/test_objects.py +31 -0
- {piccolo-1.22.0.dist-info → piccolo-1.24.0.dist-info}/LICENSE +0 -0
- {piccolo-1.22.0.dist-info → piccolo-1.24.0.dist-info}/top_level.txt +0 -0
piccolo/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__VERSION__ = "1.
|
1
|
+
__VERSION__ = "1.24.0"
|
@@ -17,6 +17,9 @@ ROUTER_DEPENDENCIES = {
|
|
17
17
|
"litestar": ["litestar"],
|
18
18
|
"esmerald": ["esmerald"],
|
19
19
|
"lilya": ["lilya"],
|
20
|
+
"quart": ["quart", "quart_schema"],
|
21
|
+
"falcon": ["falcon"],
|
22
|
+
"sanic": ["sanic", "sanic_ext"],
|
20
23
|
}
|
21
24
|
ROUTERS = list(ROUTER_DEPENDENCIES.keys())
|
22
25
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
import os
|
2
|
+
import typing as t
|
3
|
+
|
4
|
+
import falcon.asgi
|
5
|
+
from hypercorn.middleware import DispatcherMiddleware
|
6
|
+
from piccolo.engine import engine_finder
|
7
|
+
from piccolo_admin.endpoints import create_admin
|
8
|
+
from piccolo_api.crud.endpoints import PiccoloCRUD
|
9
|
+
|
10
|
+
from home.endpoints import HomeEndpoint
|
11
|
+
from home.piccolo_app import APP_CONFIG
|
12
|
+
from home.tables import Task
|
13
|
+
|
14
|
+
|
15
|
+
async def open_database_connection_pool():
|
16
|
+
try:
|
17
|
+
engine = engine_finder()
|
18
|
+
await engine.start_connection_pool()
|
19
|
+
except Exception:
|
20
|
+
print("Unable to connect to the database")
|
21
|
+
|
22
|
+
|
23
|
+
async def close_database_connection_pool():
|
24
|
+
try:
|
25
|
+
engine = engine_finder()
|
26
|
+
await engine.close_connection_pool()
|
27
|
+
except Exception:
|
28
|
+
print("Unable to connect to the database")
|
29
|
+
|
30
|
+
|
31
|
+
class LifespanMiddleware:
|
32
|
+
async def process_startup(
|
33
|
+
self, scope: t.Dict[str, t.Any], event: t.Dict[str, t.Any]
|
34
|
+
) -> None:
|
35
|
+
await open_database_connection_pool()
|
36
|
+
|
37
|
+
async def process_shutdown(
|
38
|
+
self, scope: t.Dict[str, t.Any], event: t.Dict[str, t.Any]
|
39
|
+
) -> None:
|
40
|
+
await close_database_connection_pool()
|
41
|
+
|
42
|
+
|
43
|
+
app: t.Any = falcon.asgi.App(middleware=LifespanMiddleware())
|
44
|
+
app.add_static_route("/static", directory=os.path.abspath("static"))
|
45
|
+
app.add_route("/", HomeEndpoint())
|
46
|
+
|
47
|
+
PICCOLO_CRUD: t.Any = PiccoloCRUD(table=Task)
|
48
|
+
|
49
|
+
# enable the Admin and PiccoloCrud app using DispatcherMiddleware
|
50
|
+
app = DispatcherMiddleware( # type: ignore
|
51
|
+
{
|
52
|
+
"/admin": create_admin(
|
53
|
+
tables=APP_CONFIG.table_classes,
|
54
|
+
# Required when running under HTTPS:
|
55
|
+
# allowed_hosts=['my_site.com']
|
56
|
+
),
|
57
|
+
"/tasks": PICCOLO_CRUD,
|
58
|
+
"": app,
|
59
|
+
}
|
60
|
+
)
|
@@ -0,0 +1,119 @@
|
|
1
|
+
import typing as t
|
2
|
+
from http import HTTPStatus
|
3
|
+
|
4
|
+
from hypercorn.middleware import DispatcherMiddleware
|
5
|
+
from piccolo.engine import engine_finder
|
6
|
+
from piccolo_admin.endpoints import create_admin
|
7
|
+
from piccolo_api.crud.serializers import create_pydantic_model
|
8
|
+
from quart import Quart
|
9
|
+
from quart_schema import (
|
10
|
+
Info,
|
11
|
+
QuartSchema,
|
12
|
+
hide,
|
13
|
+
tag,
|
14
|
+
validate_request,
|
15
|
+
validate_response,
|
16
|
+
)
|
17
|
+
|
18
|
+
from home.endpoints import index
|
19
|
+
from home.piccolo_app import APP_CONFIG
|
20
|
+
from home.tables import Task
|
21
|
+
|
22
|
+
|
23
|
+
app = Quart(__name__, static_folder="static")
|
24
|
+
QuartSchema(app, info=Info(title="Quart API", version="0.1.0"))
|
25
|
+
|
26
|
+
|
27
|
+
TaskModelIn: t.Any = create_pydantic_model(
|
28
|
+
table=Task,
|
29
|
+
model_name="TaskModelIn",
|
30
|
+
)
|
31
|
+
TaskModelOut: t.Any = create_pydantic_model(
|
32
|
+
table=Task,
|
33
|
+
include_default_columns=True,
|
34
|
+
model_name="TaskModelOut",
|
35
|
+
)
|
36
|
+
|
37
|
+
|
38
|
+
@app.get("/")
|
39
|
+
@hide
|
40
|
+
def home():
|
41
|
+
return index()
|
42
|
+
|
43
|
+
|
44
|
+
@app.get("/tasks/")
|
45
|
+
@validate_response(t.List[TaskModelOut])
|
46
|
+
@tag(["Task"])
|
47
|
+
async def tasks():
|
48
|
+
return await Task.select().order_by(Task._meta.primary_key, ascending=False)
|
49
|
+
|
50
|
+
|
51
|
+
@app.post("/tasks/")
|
52
|
+
@validate_request(TaskModelIn)
|
53
|
+
@validate_response(TaskModelOut)
|
54
|
+
@tag(["Task"])
|
55
|
+
async def create_task(data: TaskModelIn):
|
56
|
+
task = Task(**data.model_dump())
|
57
|
+
await task.save()
|
58
|
+
return task.to_dict(), HTTPStatus.CREATED
|
59
|
+
|
60
|
+
|
61
|
+
@app.put("/tasks/<int:task_id>/")
|
62
|
+
@validate_request(TaskModelIn)
|
63
|
+
@validate_response(TaskModelOut)
|
64
|
+
@tag(["Task"])
|
65
|
+
async def update_task(task_id: int, data: TaskModelIn):
|
66
|
+
task = await Task.objects().get(Task._meta.primary_key == task_id)
|
67
|
+
if not task:
|
68
|
+
return {}, HTTPStatus.NOT_FOUND
|
69
|
+
|
70
|
+
for key, value in data.model_dump().items():
|
71
|
+
setattr(task, key, value)
|
72
|
+
|
73
|
+
await task.save()
|
74
|
+
|
75
|
+
return task.to_dict(), HTTPStatus.OK
|
76
|
+
|
77
|
+
|
78
|
+
@app.delete("/tasks/<int:task_id>/")
|
79
|
+
@validate_response(TaskModelOut)
|
80
|
+
@tag(["Task"])
|
81
|
+
async def delete_task(task_id: int):
|
82
|
+
task = await Task.objects().get(Task._meta.primary_key == task_id)
|
83
|
+
if not task:
|
84
|
+
return {}, HTTPStatus.NOT_FOUND
|
85
|
+
|
86
|
+
await task.remove()
|
87
|
+
|
88
|
+
return {}, HTTPStatus.OK
|
89
|
+
|
90
|
+
|
91
|
+
@app.before_serving
|
92
|
+
async def open_database_connection_pool():
|
93
|
+
try:
|
94
|
+
engine = engine_finder()
|
95
|
+
await engine.start_connection_pool()
|
96
|
+
except Exception:
|
97
|
+
print("Unable to connect to the database")
|
98
|
+
|
99
|
+
|
100
|
+
@app.after_serving
|
101
|
+
async def close_database_connection_pool():
|
102
|
+
try:
|
103
|
+
engine = engine_finder()
|
104
|
+
await engine.close_connection_pool()
|
105
|
+
except Exception:
|
106
|
+
print("Unable to connect to the database")
|
107
|
+
|
108
|
+
|
109
|
+
# enable the admin application using DispatcherMiddleware
|
110
|
+
app = DispatcherMiddleware( # type: ignore
|
111
|
+
{
|
112
|
+
"/admin": create_admin(
|
113
|
+
tables=APP_CONFIG.table_classes,
|
114
|
+
# Required when running under HTTPS:
|
115
|
+
# allowed_hosts=['my_site.com']
|
116
|
+
),
|
117
|
+
"": app,
|
118
|
+
}
|
119
|
+
)
|
@@ -0,0 +1,121 @@
|
|
1
|
+
import asyncio
|
2
|
+
import typing as t
|
3
|
+
|
4
|
+
from hypercorn.middleware import DispatcherMiddleware
|
5
|
+
from piccolo.engine import engine_finder
|
6
|
+
from piccolo_admin.endpoints import create_admin
|
7
|
+
from piccolo_api.crud.serializers import create_pydantic_model
|
8
|
+
from sanic import Request, Sanic, json
|
9
|
+
from sanic_ext import openapi
|
10
|
+
|
11
|
+
from home.endpoints import index
|
12
|
+
from home.piccolo_app import APP_CONFIG
|
13
|
+
from home.tables import Task
|
14
|
+
|
15
|
+
app = Sanic(__name__)
|
16
|
+
app.static("/static/", "static")
|
17
|
+
|
18
|
+
|
19
|
+
TaskModelIn: t.Any = create_pydantic_model(
|
20
|
+
table=Task,
|
21
|
+
model_name="TaskModelIn",
|
22
|
+
)
|
23
|
+
TaskModelOut: t.Any = create_pydantic_model(
|
24
|
+
table=Task,
|
25
|
+
include_default_columns=True,
|
26
|
+
model_name="TaskModelOut",
|
27
|
+
)
|
28
|
+
|
29
|
+
|
30
|
+
@app.get("/")
|
31
|
+
@openapi.exclude()
|
32
|
+
def home(request: Request):
|
33
|
+
return index()
|
34
|
+
|
35
|
+
|
36
|
+
@app.get("/tasks/")
|
37
|
+
@openapi.tag("Task")
|
38
|
+
@openapi.response(200, {"application/json": TaskModelOut.model_json_schema()})
|
39
|
+
async def tasks(request: Request):
|
40
|
+
return json(
|
41
|
+
await Task.select().order_by(Task._meta.primary_key, ascending=False),
|
42
|
+
status=200,
|
43
|
+
)
|
44
|
+
|
45
|
+
|
46
|
+
@app.post("/tasks/")
|
47
|
+
@openapi.definition(
|
48
|
+
body={"application/json": TaskModelIn.model_json_schema()},
|
49
|
+
tag="Task",
|
50
|
+
)
|
51
|
+
@openapi.response(201, {"application/json": TaskModelOut.model_json_schema()})
|
52
|
+
async def create_task(request: Request):
|
53
|
+
task = Task(**request.json)
|
54
|
+
await task.save()
|
55
|
+
return json(task.to_dict(), status=201)
|
56
|
+
|
57
|
+
|
58
|
+
@app.put("/tasks/<task_id:int>/")
|
59
|
+
@openapi.definition(
|
60
|
+
body={"application/json": TaskModelIn.model_json_schema()},
|
61
|
+
tag="Task",
|
62
|
+
)
|
63
|
+
@openapi.response(200, {"application/json": TaskModelOut.model_json_schema()})
|
64
|
+
async def update_task(request: Request, task_id: int):
|
65
|
+
task = await Task.objects().get(Task._meta.primary_key == task_id)
|
66
|
+
if not task:
|
67
|
+
return json({}, status=404)
|
68
|
+
for key, value in request.json.items():
|
69
|
+
setattr(task, key, value)
|
70
|
+
|
71
|
+
await task.save()
|
72
|
+
return json(task.to_dict(), status=200)
|
73
|
+
|
74
|
+
|
75
|
+
@app.delete("/tasks/<task_id:int>/")
|
76
|
+
@openapi.tag("Task")
|
77
|
+
async def delete_task(request: Request, task_id: int):
|
78
|
+
task = await Task.objects().get(Task._meta.primary_key == task_id)
|
79
|
+
if not task:
|
80
|
+
return json({}, status=404)
|
81
|
+
await task.remove()
|
82
|
+
return json({}, status=200)
|
83
|
+
|
84
|
+
|
85
|
+
async def open_database_connection_pool():
|
86
|
+
try:
|
87
|
+
engine = engine_finder()
|
88
|
+
await engine.start_connection_pool()
|
89
|
+
except Exception:
|
90
|
+
print("Unable to connect to the database")
|
91
|
+
|
92
|
+
|
93
|
+
async def close_database_connection_pool():
|
94
|
+
try:
|
95
|
+
engine = engine_finder()
|
96
|
+
await engine.close_connection_pool()
|
97
|
+
except Exception:
|
98
|
+
print("Unable to connect to the database")
|
99
|
+
|
100
|
+
|
101
|
+
@app.after_server_start
|
102
|
+
async def startup(app, loop):
|
103
|
+
await open_database_connection_pool()
|
104
|
+
|
105
|
+
|
106
|
+
@app.before_server_stop
|
107
|
+
async def shutdown(app, loop):
|
108
|
+
await close_database_connection_pool()
|
109
|
+
|
110
|
+
|
111
|
+
# enable the admin application using DispatcherMiddleware
|
112
|
+
app = DispatcherMiddleware( # type: ignore
|
113
|
+
{
|
114
|
+
"/admin": create_admin(
|
115
|
+
tables=APP_CONFIG.table_classes,
|
116
|
+
# Required when running under HTTPS:
|
117
|
+
# allowed_hosts=['my_site.com']
|
118
|
+
),
|
119
|
+
"": app,
|
120
|
+
}
|
121
|
+
)
|
@@ -10,4 +10,10 @@
|
|
10
10
|
{% include '_esmerald_app.py.jinja' %}
|
11
11
|
{% elif router == 'lilya' %}
|
12
12
|
{% include '_lilya_app.py.jinja' %}
|
13
|
+
{% elif router == 'quart' %}
|
14
|
+
{% include '_quart_app.py.jinja' %}
|
15
|
+
{% elif router == 'falcon' %}
|
16
|
+
{% include '_falcon_app.py.jinja' %}
|
17
|
+
{% elif router == 'sanic' %}
|
18
|
+
{% include '_sanic_app.py.jinja' %}
|
13
19
|
{% endif %}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
import falcon
|
4
|
+
import jinja2
|
5
|
+
|
6
|
+
ENVIRONMENT = jinja2.Environment(
|
7
|
+
loader=jinja2.FileSystemLoader(
|
8
|
+
searchpath=os.path.join(os.path.dirname(__file__), "templates")
|
9
|
+
)
|
10
|
+
)
|
11
|
+
|
12
|
+
|
13
|
+
class HomeEndpoint:
|
14
|
+
async def on_get(self, req, resp):
|
15
|
+
template = ENVIRONMENT.get_template("home.html.jinja")
|
16
|
+
content = template.render(title="Piccolo + ASGI",)
|
17
|
+
resp.status = falcon.HTTP_200
|
18
|
+
resp.content_type = "text/html"
|
19
|
+
resp.text = content
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
import jinja2
|
4
|
+
|
5
|
+
from quart import Response
|
6
|
+
|
7
|
+
ENVIRONMENT = jinja2.Environment(
|
8
|
+
loader=jinja2.FileSystemLoader(
|
9
|
+
searchpath=os.path.join(os.path.dirname(__file__), "templates")
|
10
|
+
)
|
11
|
+
)
|
12
|
+
|
13
|
+
|
14
|
+
def index():
|
15
|
+
template = ENVIRONMENT.get_template("home.html.jinja")
|
16
|
+
content = template.render(title="Piccolo + ASGI")
|
17
|
+
return Response(content)
|
18
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
import jinja2
|
4
|
+
|
5
|
+
from sanic import HTTPResponse
|
6
|
+
|
7
|
+
ENVIRONMENT = jinja2.Environment(
|
8
|
+
loader=jinja2.FileSystemLoader(
|
9
|
+
searchpath=os.path.join(os.path.dirname(__file__), "templates")
|
10
|
+
)
|
11
|
+
)
|
12
|
+
|
13
|
+
|
14
|
+
def index():
|
15
|
+
template = ENVIRONMENT.get_template("home.html.jinja")
|
16
|
+
content = template.render(title="Piccolo + ASGI")
|
17
|
+
return HTTPResponse(content)
|
@@ -8,4 +8,10 @@
|
|
8
8
|
{% include '_esmerald_endpoints.py.jinja' %}
|
9
9
|
{% elif router == 'lilya' %}
|
10
10
|
{% include '_lilya_endpoints.py.jinja' %}
|
11
|
+
{% elif router == 'quart' %}
|
12
|
+
{% include '_quart_endpoints.py.jinja' %}
|
13
|
+
{% elif router == 'falcon' %}
|
14
|
+
{% include '_falcon_endpoints.py.jinja' %}
|
15
|
+
{% elif router == 'sanic' %}
|
16
|
+
{% include '_sanic_endpoints.py.jinja' %}
|
11
17
|
{% endif %}
|
@@ -66,6 +66,21 @@
|
|
66
66
|
<li><a href="/admin/">Admin</a></li>
|
67
67
|
<li><a href="/tasks/">JSON endpoint</a></li>
|
68
68
|
</ul>
|
69
|
+
<h3>Quart</h3>
|
70
|
+
<ul>
|
71
|
+
<li><a href="/admin/">Admin</a></li>
|
72
|
+
<li><a href="/docs">Swagger API</a></li>
|
73
|
+
</ul>
|
74
|
+
<h3>Falcon</h3>
|
75
|
+
<ul>
|
76
|
+
<li><a href="/admin/">Admin</a></li>
|
77
|
+
<li><a href="/tasks/">JSON endpoint</a></li>
|
78
|
+
</ul>
|
79
|
+
<h3>Sanic</h3>
|
80
|
+
<ul>
|
81
|
+
<li><a href="/admin/">Admin</a></li>
|
82
|
+
<li><a href="/docs/swagger">Swagger API</a></li>
|
83
|
+
</ul>
|
69
84
|
</section>
|
70
85
|
</div>
|
71
86
|
{% endblock content %}
|
@@ -28,24 +28,23 @@ def run() -> None:
|
|
28
28
|
|
29
29
|
args = ["psql"]
|
30
30
|
|
31
|
-
|
32
|
-
port = engine.config.get("port")
|
33
|
-
user = engine.config.get("user")
|
34
|
-
password = engine.config.get("password")
|
35
|
-
database = engine.config.get("database")
|
31
|
+
config = engine.config
|
36
32
|
|
37
|
-
if
|
38
|
-
args += [
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
33
|
+
if dsn := config.get("dsn"):
|
34
|
+
args += [dsn]
|
35
|
+
else:
|
36
|
+
if user := config.get("user"):
|
37
|
+
args += ["-U", user]
|
38
|
+
if host := config.get("host"):
|
39
|
+
args += ["-h", host]
|
40
|
+
if port := config.get("port"):
|
41
|
+
args += ["-p", str(port)]
|
42
|
+
if database := config.get("database"):
|
43
|
+
args += [database]
|
45
44
|
|
46
45
|
sigint_handler = signal.getsignal(signal.SIGINT)
|
47
46
|
subprocess_env = os.environ.copy()
|
48
|
-
if password:
|
47
|
+
if password := config.get("password"):
|
49
48
|
subprocess_env["PGPASSWORD"] = str(password)
|
50
49
|
try:
|
51
50
|
# Allow SIGINT to pass to psql to abort queries.
|
piccolo/apps/user/tables.py
CHANGED
@@ -202,7 +202,9 @@ class BaseUser(Table, tablename="piccolo_user"):
|
|
202
202
|
The id of the user if a match is found, otherwise ``None``.
|
203
203
|
|
204
204
|
"""
|
205
|
-
if
|
205
|
+
if (max_username_length := cls.username.length) and len(
|
206
|
+
username
|
207
|
+
) > max_username_length:
|
206
208
|
logger.warning("Excessively long username provided.")
|
207
209
|
return None
|
208
210
|
|
piccolo/columns/column_types.py
CHANGED
piccolo/engine/sqlite.py
CHANGED
@@ -173,9 +173,21 @@ def convert_numeric_out(value: str) -> Decimal:
|
|
173
173
|
@decode_to_string
|
174
174
|
def convert_int_out(value: str) -> int:
|
175
175
|
"""
|
176
|
-
Make sure
|
176
|
+
Make sure INTEGER values are actually of type ``int``.
|
177
|
+
|
178
|
+
SQLite doesn't enforce that the values in INTEGER columns are actually
|
179
|
+
integers - they could be strings ('hello'), or floats (1.0).
|
180
|
+
|
181
|
+
There's not much we can do if the value is something like 'hello' - a
|
182
|
+
``ValueError`` is appropriate in this situation.
|
183
|
+
|
184
|
+
For a value like ``1.0``, it seems reasonable to handle this, and return a
|
185
|
+
value of ``1``.
|
186
|
+
|
177
187
|
"""
|
178
|
-
|
188
|
+
# We used to use int(float(value)), but it was incorrect, because float has
|
189
|
+
# limited precision for large numbers.
|
190
|
+
return int(Decimal(value))
|
179
191
|
|
180
192
|
|
181
193
|
@decode_to_string
|
piccolo/query/methods/objects.py
CHANGED
@@ -65,22 +65,20 @@ class GetOrCreate(
|
|
65
65
|
instance._was_created = False
|
66
66
|
return instance
|
67
67
|
|
68
|
-
|
68
|
+
data = {**self.defaults}
|
69
69
|
|
70
70
|
# If it's a complex `where`, there can be several column values to
|
71
71
|
# extract e.g. (Band.name == 'Pythonistas') & (Band.popularity == 1000)
|
72
72
|
if isinstance(self.where, Where):
|
73
|
-
|
74
|
-
instance,
|
75
|
-
self.where.column._meta.name, # type: ignore
|
76
|
-
self.where.value, # type: ignore
|
77
|
-
)
|
73
|
+
data[self.where.column] = self.where.value
|
78
74
|
elif isinstance(self.where, And):
|
79
75
|
for column, value in self.where.get_column_values().items():
|
80
76
|
if len(column._meta.call_chain) == 0:
|
81
77
|
# Make sure we only set the value if the column belongs
|
82
78
|
# to this table.
|
83
|
-
|
79
|
+
data[column] = value
|
80
|
+
|
81
|
+
instance = self.table_class(_data=data)
|
84
82
|
|
85
83
|
await instance.save().run(node=node, in_pool=in_pool)
|
86
84
|
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.2
|
2
2
|
Name: piccolo
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.24.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
|
@@ -9,7 +9,6 @@ License: MIT
|
|
9
9
|
Project-URL: Documentation, https://piccolo-orm.readthedocs.io/en/latest/index.html
|
10
10
|
Project-URL: Source, https://github.com/piccolo-orm/piccolo
|
11
11
|
Project-URL: Tracker, https://github.com/piccolo-orm/piccolo/issues
|
12
|
-
Platform: UNKNOWN
|
13
12
|
Classifier: License :: OSI Approved :: MIT License
|
14
13
|
Classifier: Programming Language :: Python
|
15
14
|
Classifier: Programming Language :: Python :: 3
|
@@ -26,28 +25,40 @@ Requires-Python: >=3.9.0
|
|
26
25
|
Description-Content-Type: text/markdown
|
27
26
|
License-File: LICENSE
|
28
27
|
Requires-Dist: black
|
29
|
-
Requires-Dist: colorama
|
30
|
-
Requires-Dist: Jinja2
|
31
|
-
Requires-Dist: targ
|
32
|
-
Requires-Dist: inflection
|
33
|
-
Requires-Dist: typing-extensions
|
34
|
-
Requires-Dist: pydantic[email]
|
35
|
-
Provides-Extra: all
|
36
|
-
Requires-Dist: orjson (>=3.5.1) ; extra == 'all'
|
37
|
-
Requires-Dist: ipython ; extra == 'all'
|
38
|
-
Requires-Dist: asyncpg (>=0.30.0) ; extra == 'all'
|
39
|
-
Requires-Dist: aiosqlite (>=0.16.0) ; extra == 'all'
|
40
|
-
Requires-Dist: uvloop (>=0.12.0) ; (sys_platform != "win32") and extra == 'all'
|
28
|
+
Requires-Dist: colorama>=0.4.0
|
29
|
+
Requires-Dist: Jinja2>=2.11.0
|
30
|
+
Requires-Dist: targ>=0.3.7
|
31
|
+
Requires-Dist: inflection>=0.5.1
|
32
|
+
Requires-Dist: typing-extensions>=4.3.0
|
33
|
+
Requires-Dist: pydantic[email]==2.*
|
41
34
|
Provides-Extra: orjson
|
42
|
-
Requires-Dist: orjson
|
35
|
+
Requires-Dist: orjson>=3.5.1; extra == "orjson"
|
43
36
|
Provides-Extra: playground
|
44
|
-
Requires-Dist: ipython
|
37
|
+
Requires-Dist: ipython; extra == "playground"
|
45
38
|
Provides-Extra: postgres
|
46
|
-
Requires-Dist: asyncpg
|
39
|
+
Requires-Dist: asyncpg>=0.30.0; extra == "postgres"
|
47
40
|
Provides-Extra: sqlite
|
48
|
-
Requires-Dist: aiosqlite
|
41
|
+
Requires-Dist: aiosqlite>=0.16.0; extra == "sqlite"
|
49
42
|
Provides-Extra: uvloop
|
50
|
-
Requires-Dist: uvloop
|
43
|
+
Requires-Dist: uvloop>=0.12.0; sys_platform != "win32" and extra == "uvloop"
|
44
|
+
Provides-Extra: all
|
45
|
+
Requires-Dist: orjson>=3.5.1; extra == "all"
|
46
|
+
Requires-Dist: ipython; extra == "all"
|
47
|
+
Requires-Dist: asyncpg>=0.30.0; extra == "all"
|
48
|
+
Requires-Dist: aiosqlite>=0.16.0; extra == "all"
|
49
|
+
Requires-Dist: uvloop>=0.12.0; sys_platform != "win32" and extra == "all"
|
50
|
+
Dynamic: author
|
51
|
+
Dynamic: author-email
|
52
|
+
Dynamic: classifier
|
53
|
+
Dynamic: description
|
54
|
+
Dynamic: description-content-type
|
55
|
+
Dynamic: home-page
|
56
|
+
Dynamic: license
|
57
|
+
Dynamic: project-url
|
58
|
+
Dynamic: provides-extra
|
59
|
+
Dynamic: requires-dist
|
60
|
+
Dynamic: requires-python
|
61
|
+
Dynamic: summary
|
51
62
|
|
52
63
|

|
53
64
|
|
@@ -145,7 +156,7 @@ Let Piccolo scaffold you an ASGI web app, using Piccolo as the ORM:
|
|
145
156
|
piccolo asgi new
|
146
157
|
```
|
147
158
|
|
148
|
-
[Starlette](https://www.starlette.io/), [FastAPI](https://fastapi.tiangolo.com/), [BlackSheep](https://www.neoteroi.dev/blacksheep/), [Litestar](https://litestar.dev/), [Esmerald](https://esmerald.dev/)
|
159
|
+
[Starlette](https://www.starlette.io/), [FastAPI](https://fastapi.tiangolo.com/), [BlackSheep](https://www.neoteroi.dev/blacksheep/), [Litestar](https://litestar.dev/), [Esmerald](https://esmerald.dev/), [Lilya](https://lilya.dev), [Quart](https://quart.palletsprojects.com/en/latest/), [Falcon](https://falconframework.org/) and [Sanic](https://sanic.dev/en/) are currently supported.
|
149
160
|
|
150
161
|
## Are you a Django user?
|
151
162
|
|
@@ -156,5 +167,3 @@ We have a handy page which shows the equivalent of [common Django queries in Pic
|
|
156
167
|
Our documentation is on [Read the docs](https://piccolo-orm.readthedocs.io/en/latest/piccolo/getting_started/index.html).
|
157
168
|
|
158
169
|
We also have some great [tutorial videos on YouTube](https://www.youtube.com/channel/UCE7x5nm1Iy9KDfXPNrNQ5lA).
|
159
|
-
|
160
|
-
|
@@ -1,4 +1,4 @@
|
|
1
|
-
piccolo/__init__.py,sha256=
|
1
|
+
piccolo/__init__.py,sha256=uyuLf5Q7X3vuYYBK0p5G67YV-evr3rtlsYxNysnS3W8,23
|
2
2
|
piccolo/custom_types.py,sha256=7HMQAze-5mieNLfbQ5QgbRQgR2abR7ol0qehv2SqROY,604
|
3
3
|
piccolo/main.py,sha256=1VsFV67FWTUikPTysp64Fmgd9QBVa_9wcwKfwj2UCEA,5117
|
4
4
|
piccolo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -17,15 +17,18 @@ piccolo/apps/app/commands/templates/tables.py.jinja,sha256=revzdrvDDwe78VedBKz0z
|
|
17
17
|
piccolo/apps/asgi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
18
18
|
piccolo/apps/asgi/piccolo_app.py,sha256=7VUvqQJbB-ScO0A62S6MiJmQL9F5DS-SdlqlDLbAblE,217
|
19
19
|
piccolo/apps/asgi/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
|
-
piccolo/apps/asgi/commands/new.py,sha256=
|
20
|
+
piccolo/apps/asgi/commands/new.py,sha256=718mXx7XdDTN0CKK0ZB1WVMkOrQtVfqT5bqO1kDKnRk,4335
|
21
21
|
piccolo/apps/asgi/commands/templates/app/README.md.jinja,sha256=As3gNEZt9qcRmTVkjCzNtXJ8r4-3g0fCSe7Q-P39ezI,214
|
22
22
|
piccolo/apps/asgi/commands/templates/app/_blacksheep_app.py.jinja,sha256=IKOql1G5wrEKm5qErlizOmrwYKlnxkm-d8NY5uVg9KA,3186
|
23
23
|
piccolo/apps/asgi/commands/templates/app/_esmerald_app.py.jinja,sha256=nTzXc5IJLl_al1FuzG5AnaA1vSn-ipMurpPK7BibmB8,2710
|
24
|
+
piccolo/apps/asgi/commands/templates/app/_falcon_app.py.jinja,sha256=LOn3auJFeXNW48rtHzRbH3MzxWbRNhFib6Fm6wDS53E,1684
|
24
25
|
piccolo/apps/asgi/commands/templates/app/_fastapi_app.py.jinja,sha256=mKnYfUOnYyWJA1jFoRLCUOGQlK6imaxx_1qaauGjeeQ,2627
|
25
26
|
piccolo/apps/asgi/commands/templates/app/_lilya_app.py.jinja,sha256=PUph5Jj_AXVpxXZmpUzzHXogUchU8vjKBL_7WvgrfCU,1260
|
26
27
|
piccolo/apps/asgi/commands/templates/app/_litestar_app.py.jinja,sha256=VCY4FoA7YlEhtjWB09XWQqi8GgL36VQwGGBpSXUDO5o,3349
|
28
|
+
piccolo/apps/asgi/commands/templates/app/_quart_app.py.jinja,sha256=3LoQJ6LWRB0NFIcfQtPUdNWb10csyDGgCIa2zx8w4e8,2837
|
29
|
+
piccolo/apps/asgi/commands/templates/app/_sanic_app.py.jinja,sha256=qza84-aV6wnPlPQ9bpcD5DLO-pvkmoSnb_lXmcymv6c,3159
|
27
30
|
piccolo/apps/asgi/commands/templates/app/_starlette_app.py.jinja,sha256=vHcAzsS9I3OevYoznwZp8zucI4OEyUjj-EOAtscmlSE,1443
|
28
|
-
piccolo/apps/asgi/commands/templates/app/app.py.jinja,sha256=
|
31
|
+
piccolo/apps/asgi/commands/templates/app/app.py.jinja,sha256=n2KriWxCnq65vdEvX1USTqZPDbNkYXQqTJT5EmespT8,667
|
29
32
|
piccolo/apps/asgi/commands/templates/app/conftest.py.jinja,sha256=ZG1pRVMv3LhIfOsO3_08c_fF3EV4_EApuDHiIFFPJdk,497
|
30
33
|
piccolo/apps/asgi/commands/templates/app/main.py.jinja,sha256=QxMpsevsxGQdL_xwfvcNalGLXGswgqiVvApitkP1TuQ,533
|
31
34
|
piccolo/apps/asgi/commands/templates/app/piccolo_conf.py.jinja,sha256=f9Nb08_yipi0_mDUYrUvVoGCz7MRRS5QjCdUGBHN760,379
|
@@ -34,15 +37,18 @@ piccolo/apps/asgi/commands/templates/app/requirements.txt.jinja,sha256=w4FXnehMN
|
|
34
37
|
piccolo/apps/asgi/commands/templates/app/home/__init__.py.jinja,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
38
|
piccolo/apps/asgi/commands/templates/app/home/_blacksheep_endpoints.py.jinja,sha256=Rri_xzDkl87G5ME74qTxY25cwKIKufuzgkRsy__mNts,510
|
36
39
|
piccolo/apps/asgi/commands/templates/app/home/_esmerald_endpoints.py.jinja,sha256=D_Slfc3IfTyBgq_VUIG5_AW5pVvvSqn-YGQspxMJNsE,499
|
40
|
+
piccolo/apps/asgi/commands/templates/app/home/_falcon_endpoints.py.jinja,sha256=Fv3MQnCF7oK752yjpJp35ONpj6wlu2Kld1kxYphdcOs,479
|
37
41
|
piccolo/apps/asgi/commands/templates/app/home/_lilya_endpoints.py.jinja,sha256=nKSJ9VPTUTaLD9oDqAUseNuQkcPLBxShPAEfZK15rSE,490
|
38
42
|
piccolo/apps/asgi/commands/templates/app/home/_litestar_endpoints.py.jinja,sha256=zXbYXDXFeeOCXmWBa_QK0kWGlBnv6T_A2jOHuvp9oCs,553
|
43
|
+
piccolo/apps/asgi/commands/templates/app/home/_quart_endpoints.py.jinja,sha256=V92EMVnQusgov_i2KC4wa4GiSIDxBLezgKUrT2YPiuc,365
|
44
|
+
piccolo/apps/asgi/commands/templates/app/home/_sanic_endpoints.py.jinja,sha256=8Bcq1uVxme8hfDlnenyBS19d0EzwBK2BZ64C91k_F50,368
|
39
45
|
piccolo/apps/asgi/commands/templates/app/home/_starlette_endpoints.py.jinja,sha256=KEjNEUKiZNBIWYAt9EgPHe4yCbkKLtlhaCBce9YI-RQ,498
|
40
|
-
piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja,sha256=
|
46
|
+
piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja,sha256=9S8oXL2I67BLhFehvYU6Ce5pbCeqhwVHhT0SQW5ZMOw,655
|
41
47
|
piccolo/apps/asgi/commands/templates/app/home/piccolo_app.py.jinja,sha256=4gETiW9ukTNsomeJOvrRkqPbToZ_FU0b3LsNIaEYyP8,505
|
42
48
|
piccolo/apps/asgi/commands/templates/app/home/tables.py.jinja,sha256=wk34RAsuoFn5iJ4OHlQzUqgatq6QB2G9tFE0BYkaers,197
|
43
49
|
piccolo/apps/asgi/commands/templates/app/home/piccolo_migrations/README.md,sha256=ji6UOtHvzHX-eS_qhhKTN36ZXNZ7QwtjwjdE4Qgm35A,59
|
44
50
|
piccolo/apps/asgi/commands/templates/app/home/templates/base.html.jinja_raw,sha256=3RqiNuyAap_P-xNK3uhNaQQ6rC365VzPmRqmmXSLO8o,451
|
45
|
-
piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw,sha256=
|
51
|
+
piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw,sha256=dD6OAlzfJV_fZktv5b9ek3lJcqDMxTdAkRJzmRDIH0g,3166
|
46
52
|
piccolo/apps/asgi/commands/templates/app/static/favicon.ico,sha256=IvcgeJHObd9kj2mNIXkJdXYxMU8OaOymyYQWnWfbtHo,7406
|
47
53
|
piccolo/apps/asgi/commands/templates/app/static/main.css,sha256=vudarPLglQ6NOgJiNeU2x0yQl0DiWScqb09QZv2wAzM,1056
|
48
54
|
piccolo/apps/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -97,14 +103,14 @@ piccolo/apps/shell/commands/run.py,sha256=BiGMnM0wGKNvZOklgQeU_ZhBYWFxtsTQuvVHdo
|
|
97
103
|
piccolo/apps/sql_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
98
104
|
piccolo/apps/sql_shell/piccolo_app.py,sha256=uFuMQIPLSMYi7y5x3wG1LPqGmEkwC-dYlmLTKrBaUQQ,221
|
99
105
|
piccolo/apps/sql_shell/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
100
|
-
piccolo/apps/sql_shell/commands/run.py,sha256=
|
106
|
+
piccolo/apps/sql_shell/commands/run.py,sha256=mOt0kuJ_-QhKXrlt0Ceicx4JxxCLlK6OwUyB_HQpLiI,2097
|
101
107
|
piccolo/apps/tester/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
102
108
|
piccolo/apps/tester/piccolo_app.py,sha256=LAAzW3SdVKZjvVXpBxwprYxV0rJbeDD3CB5JpRmHm8k,225
|
103
109
|
piccolo/apps/tester/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
104
110
|
piccolo/apps/tester/commands/run.py,sha256=phFxim2ogARAviW-YT11y9F-L5SJxSioAIepUzQeAWU,2431
|
105
111
|
piccolo/apps/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
106
112
|
piccolo/apps/user/piccolo_app.py,sha256=yfw1J9FEnBWdgGdUdNMnqp06Wzm5_s9TO2r5KLchrLM,842
|
107
|
-
piccolo/apps/user/tables.py,sha256=
|
113
|
+
piccolo/apps/user/tables.py,sha256=QD8FD3qhtBqfFAkAMjQVqTnxrPmwa_V2uzVzk16eRaU,9153
|
108
114
|
piccolo/apps/user/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
109
115
|
piccolo/apps/user/commands/change_password.py,sha256=F7mlhtTUY7uENSK8vds5oibIDJTz7QBQdrl7EB-lF9Q,649
|
110
116
|
piccolo/apps/user/commands/change_permissions.py,sha256=LScsKJUMJqIi54cZ1SgS9Wb356KB0t7smu94FDXLfVk,1463
|
@@ -117,7 +123,7 @@ piccolo/apps/user/piccolo_migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
|
|
117
123
|
piccolo/columns/__init__.py,sha256=OYhO_n9anMiU9nL-K6ATq9FhAtm8RyMpqYQ7fTVbhxI,1120
|
118
124
|
piccolo/columns/base.py,sha256=_bg9yMWjMwE76Z7RDqi9iYSmtRuFx5bkx9uYJsFHKjQ,32487
|
119
125
|
piccolo/columns/choices.py,sha256=-HNQuk9vMmVZIPZ5PMeXGTfr23o4nzKPSAkvcG1k0y8,723
|
120
|
-
piccolo/columns/column_types.py,sha256=
|
126
|
+
piccolo/columns/column_types.py,sha256=Wo6g14aL1vpOFugsY-6n-q6JUJaKih-cIn9NBp-f3fI,84759
|
121
127
|
piccolo/columns/combination.py,sha256=vMXC2dfY7pvnCFhsT71XFVyb4gdQzfRsCMaiduu04Ss,6900
|
122
128
|
piccolo/columns/indexes.py,sha256=NfNok3v_791jgDlN28KmhP9ZCjl6031BXmjxV3ovXJk,372
|
123
129
|
piccolo/columns/m2m.py,sha256=QMeSOnm4DT2cG9U5jC6sOZ6z9DxCWwDyZMSqk0wR2q4,14682
|
@@ -129,7 +135,7 @@ piccolo/columns/defaults/date.py,sha256=Duuyi-QJ9Rr72aJkCNnjyO1CJBE-inZNGKnyV8tb
|
|
129
135
|
piccolo/columns/defaults/interval.py,sha256=ypaQpgDm1AL0WTMFEgKCt0I-e9ADUYdRRSBl65IJdiw,1987
|
130
136
|
piccolo/columns/defaults/time.py,sha256=2e0SDjl9_Mrw2YUeLFXDDYhmlC9Qjek3MkhvmWKQFH0,2417
|
131
137
|
piccolo/columns/defaults/timestamp.py,sha256=3Ng_LJ76nic-3j_AIzZfUvj3djIFRVkps98w1b_2lUM,3565
|
132
|
-
piccolo/columns/defaults/timestamptz.py,sha256=
|
138
|
+
piccolo/columns/defaults/timestamptz.py,sha256=RMw9wW20NbvaG_HY-0amBRuD-OLde4at_xQCf0D8NE4,2096
|
133
139
|
piccolo/columns/defaults/uuid.py,sha256=zBBaXlUsDTKcxRFDWwqgpiDRrYd7ptxC_hf7UqYhRjY,470
|
134
140
|
piccolo/columns/operators/__init__.py,sha256=fIIm309C7ddqrP-M9oLlfhcZEM4Fx5B203QMzBm0OpM,310
|
135
141
|
piccolo/columns/operators/base.py,sha256=UfaqPd-ieqydrjhvcGYiwHMOKs199tTiT1gFE15DZzo,34
|
@@ -144,7 +150,7 @@ piccolo/engine/cockroach.py,sha256=gGnihplotMZMWqHwRnZYnnbKU3jFrwttwOlNtktoeLE,1
|
|
144
150
|
piccolo/engine/exceptions.py,sha256=X8xZiTF-L9PIqFT-KDXnv1jFIIOZMF8fYK692chttJE,44
|
145
151
|
piccolo/engine/finder.py,sha256=GjzBNtzRzH79fjtRn7OI3nZiOXE8JfoQWAvHVPrPNx4,507
|
146
152
|
piccolo/engine/postgres.py,sha256=DekL3KafCdzSAEQ6_EgOiUB1ERXh2xpePYwI9QvmN-c,18955
|
147
|
-
piccolo/engine/sqlite.py,sha256=
|
153
|
+
piccolo/engine/sqlite.py,sha256=Oe0GBrIUSUkutvk5LoXGWC6HFQzKeusfql5-NMssH_s,25735
|
148
154
|
piccolo/query/__init__.py,sha256=bcsMV4813rMRAIqGv4DxI4eyO4FmpXkDv9dfTk5pt3A,699
|
149
155
|
piccolo/query/base.py,sha256=sO5VyicbWjgYaQukr6jqUqUUrOctL6QJ1MjcsgDKHXM,14912
|
150
156
|
piccolo/query/mixins.py,sha256=X9HEYnj6uOjgTkGr4vgqTwN_dokJPzVagwbFx385atQ,24468
|
@@ -166,7 +172,7 @@ piccolo/query/methods/drop_index.py,sha256=5x3vHpoOmQ1SMhj6L7snKXX6M9l9j1E1PFSO6
|
|
166
172
|
piccolo/query/methods/exists.py,sha256=lTMjtrFPFygZmaPV3sfQKXc3K0sVqJ2S6PDc3fRK6YQ,1203
|
167
173
|
piccolo/query/methods/indexes.py,sha256=J-QUqaBJwpgahskUH0Cu0Mq7zEKcfVAtDsUVIVX-C4c,943
|
168
174
|
piccolo/query/methods/insert.py,sha256=ssLJ_wn08KnOwwr7t-VILyn1P4hrvM63CfPIcAJWT5k,4701
|
169
|
-
piccolo/query/methods/objects.py,sha256=
|
175
|
+
piccolo/query/methods/objects.py,sha256=wK3poKXVVTpjFgpVfmumVn9q8Qiqz0PZ4ukm7Ih-CGw,15511
|
170
176
|
piccolo/query/methods/raw.py,sha256=wQWR8b-yA_Gr-5lqRMZe9BOAAMBAw8CqTx37qVYvM1A,987
|
171
177
|
piccolo/query/methods/refresh.py,sha256=wg1zghKfwz-VmqK4uWa4GNMiDtK-skTqow591Hb3ONM,5854
|
172
178
|
piccolo/query/methods/select.py,sha256=41OW-DIE_wr5VdxSusMKNT2aUhzQsCwK2Qh1XqgXHg0,22424
|
@@ -237,7 +243,7 @@ tests/apps/shell/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
237
243
|
tests/apps/shell/commands/test_run.py,sha256=wH3ORQwJ1a02kA-WnZUCNmb0AlwXpRKoTntOZVUZAqI,1170
|
238
244
|
tests/apps/sql_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
239
245
|
tests/apps/sql_shell/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
240
|
-
tests/apps/sql_shell/commands/test_run.py,sha256=
|
246
|
+
tests/apps/sql_shell/commands/test_run.py,sha256=MDfuJdgOSEMAEXtBQYWx2N31tRHgKPPQNUpVCRTPyu8,1033
|
241
247
|
tests/apps/tester/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
242
248
|
tests/apps/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
243
249
|
tests/apps/user/test_tables.py,sha256=5ImGAWpIKxlqweGeJRMiVOHaBJxRwSzsp3GZ7x6lzCo,9807
|
@@ -259,6 +265,7 @@ tests/columns/test_db_column_name.py,sha256=0wz6y4GNGy4nhMdHmYzEnChQGpK2UhWFFKrn
|
|
259
265
|
tests/columns/test_defaults.py,sha256=rwlU1fXt3cCl7C51eLlZXqgWkE-K5W0pHvTrwkAKyCo,2896
|
260
266
|
tests/columns/test_double_precision.py,sha256=7rhcSfDkb2fBh_zEG4UGwD_GW1sy6U9-8NooHuCS09Q,544
|
261
267
|
tests/columns/test_get_sql_value.py,sha256=mKgsInN374jzV99y9mg_ZiG-AvnJgz36SZi89xL7RZM,1768
|
268
|
+
tests/columns/test_integer.py,sha256=IcIQq0gF29gTxLY3CJuXtE13-20emqisY2wRQsu80F4,772
|
262
269
|
tests/columns/test_interval.py,sha256=2M18pfoGxLLosEvwTmuC4zQkM6jWwU0Nv2fqViW3xOs,2780
|
263
270
|
tests/columns/test_json.py,sha256=_cziJvw2uT8e_4u9lKhmU56lgQeE7bEqCXYf6AzfChA,3482
|
264
271
|
tests/columns/test_jsonb.py,sha256=KXPgJTchobzHNss86Gb0CeTDlaa5S3pQ8cM3D06-7J8,8592
|
@@ -333,11 +340,11 @@ tests/table/test_exists.py,sha256=AHvhodkRof7PVd4IDdGQ2nyOj_1Cag1Rpg1H84s4jU0,28
|
|
333
340
|
tests/table/test_from_dict.py,sha256=I4PMxuzgkgi3-adaw9Gr3u5tQHexc31Vrq7RSPcPcJs,840
|
334
341
|
tests/table/test_indexes.py,sha256=VfM2FqFO8OOaL88QYQRqPX_PPniSBoPFeLPjXZ8jHBk,2073
|
335
342
|
tests/table/test_inheritance.py,sha256=AAkhEhhixVGweGe7ckzj-yypW-cj6D88Cca4-pjkwKw,3110
|
336
|
-
tests/table/test_insert.py,sha256
|
343
|
+
tests/table/test_insert.py,sha256=c7hJ1SsTiW43l_Z5KHSN3894ICzttOAsTfWN9rUOl0k,13696
|
337
344
|
tests/table/test_join.py,sha256=Ukgvjc8NweBGHM7fVFytGQYG9P9thRaMeEvWXYs2Qes,15910
|
338
345
|
tests/table/test_join_on.py,sha256=cdAV39JwHi0kIas2p9cw7mcsUv6mKLZD--_SUA0zLfI,2771
|
339
346
|
tests/table/test_metaclass.py,sha256=pMv0PHh-2a9p74bweQXCXnq1OFsJ7Gk0uWRFdCTMf58,4123
|
340
|
-
tests/table/test_objects.py,sha256=
|
347
|
+
tests/table/test_objects.py,sha256=ptbeIICOfZ2-Fl6K_Llo1SKIyQ5ngUZ-rZtgll5cMWM,9047
|
341
348
|
tests/table/test_output.py,sha256=ZnpPbgVp79JcB6E_ooWQxOpOlhkwNUlMxC-1LSIEc2Y,4304
|
342
349
|
tests/table/test_raw.py,sha256=9PTvYngQi41nYd5lKzkJdTqsEcwrdOXcvZjq-W26CwQ,1683
|
343
350
|
tests/table/test_ref.py,sha256=eYNRnYHzNMXuMbV3B1ca5EidpIg4500q6hr1ccuVaso,269
|
@@ -372,9 +379,9 @@ tests/utils/test_sql_values.py,sha256=vzxRmy16FfLZPH-sAQexBvsF9MXB8n4smr14qoEOS5
|
|
372
379
|
tests/utils/test_sync.py,sha256=9ytVo56y2vPQePvTeIi9lHIouEhWJbodl1TmzkGFrSo,799
|
373
380
|
tests/utils/test_table_reflection.py,sha256=SIzuat-IpcVj1GCFyOWKShI8YkhdOPPFH7qVrvfyPNE,3794
|
374
381
|
tests/utils/test_warnings.py,sha256=NvSC_cvJ6uZcwAGf1m-hLzETXCqprXELL8zg3TNLVMw,269
|
375
|
-
piccolo-1.
|
376
|
-
piccolo-1.
|
377
|
-
piccolo-1.
|
378
|
-
piccolo-1.
|
379
|
-
piccolo-1.
|
380
|
-
piccolo-1.
|
382
|
+
piccolo-1.24.0.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
|
383
|
+
piccolo-1.24.0.dist-info/METADATA,sha256=Bnqm6WVw_mNMp5G2xHPbJU-bIJTTQgmaiLRlXFaOhKM,5509
|
384
|
+
piccolo-1.24.0.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
385
|
+
piccolo-1.24.0.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
|
386
|
+
piccolo-1.24.0.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
|
387
|
+
piccolo-1.24.0.dist-info/RECORD,,
|
@@ -2,13 +2,37 @@ from unittest import TestCase
|
|
2
2
|
from unittest.mock import MagicMock, patch
|
3
3
|
|
4
4
|
from piccolo.apps.sql_shell.commands.run import run
|
5
|
+
from tests.base import postgres_only, sqlite_only
|
5
6
|
|
6
7
|
|
7
8
|
class TestRun(TestCase):
|
9
|
+
@postgres_only
|
8
10
|
@patch("piccolo.apps.sql_shell.commands.run.subprocess")
|
9
|
-
def
|
11
|
+
def test_psql(self, subprocess: MagicMock):
|
10
12
|
"""
|
11
|
-
|
13
|
+
Make sure psql was called correctly.
|
12
14
|
"""
|
13
15
|
run()
|
14
16
|
self.assertTrue(subprocess.run.called)
|
17
|
+
|
18
|
+
assert subprocess.run.call_args.args[0] == [
|
19
|
+
"psql",
|
20
|
+
"-U",
|
21
|
+
"postgres",
|
22
|
+
"-h",
|
23
|
+
"localhost",
|
24
|
+
"-p",
|
25
|
+
"5432",
|
26
|
+
"piccolo",
|
27
|
+
]
|
28
|
+
|
29
|
+
@sqlite_only
|
30
|
+
@patch("piccolo.apps.sql_shell.commands.run.subprocess")
|
31
|
+
def test_sqlite3(self, subprocess: MagicMock):
|
32
|
+
"""
|
33
|
+
Make sure sqlite3 was called correctly.
|
34
|
+
"""
|
35
|
+
run()
|
36
|
+
self.assertTrue(subprocess.run.called)
|
37
|
+
|
38
|
+
assert subprocess.run.call_args.args[0] == ["sqlite3", "test.sqlite"]
|
@@ -0,0 +1,32 @@
|
|
1
|
+
from piccolo.columns.column_types import Integer
|
2
|
+
from piccolo.table import Table
|
3
|
+
from piccolo.testing.test_case import AsyncTableTest
|
4
|
+
from tests.base import sqlite_only
|
5
|
+
|
6
|
+
|
7
|
+
class MyTable(Table):
|
8
|
+
integer = Integer()
|
9
|
+
|
10
|
+
|
11
|
+
@sqlite_only
|
12
|
+
class TestInteger(AsyncTableTest):
|
13
|
+
tables = [MyTable]
|
14
|
+
|
15
|
+
async def test_large_integer(self):
|
16
|
+
"""
|
17
|
+
Make sure large integers can be inserted and retrieved correctly.
|
18
|
+
|
19
|
+
There was a bug with this in SQLite:
|
20
|
+
|
21
|
+
https://github.com/piccolo-orm/piccolo/issues/1127
|
22
|
+
|
23
|
+
"""
|
24
|
+
integer = 625757527765811240
|
25
|
+
|
26
|
+
row = MyTable(integer=integer)
|
27
|
+
await row.save()
|
28
|
+
|
29
|
+
_row = MyTable.objects().first().run_sync()
|
30
|
+
assert _row is not None
|
31
|
+
|
32
|
+
self.assertEqual(_row.integer, integer)
|
tests/table/test_insert.py
CHANGED
@@ -201,7 +201,7 @@ class TestOnConflict(TestCase):
|
|
201
201
|
Make sure that a composite unique constraint can be used as a target.
|
202
202
|
|
203
203
|
We only run it on Postgres and Cockroach because we use ALTER TABLE
|
204
|
-
to add a
|
204
|
+
to add a constraint, which SQLite doesn't support.
|
205
205
|
"""
|
206
206
|
Band = self.Band
|
207
207
|
|
tests/table/test_objects.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
from piccolo.columns.column_types import ForeignKey
|
2
|
+
from piccolo.testing.test_case import AsyncTableTest
|
1
3
|
from tests.base import DBTestCase, engines_only, sqlite_only
|
2
4
|
from tests.example_apps.music.tables import Band, Manager
|
3
5
|
|
@@ -268,3 +270,32 @@ class TestGetOrCreate(DBTestCase):
|
|
268
270
|
self.assertIsInstance(band.manager, Manager)
|
269
271
|
self.assertEqual(band.name, "New Band 2")
|
270
272
|
self.assertEqual(band.manager.name, "Guido")
|
273
|
+
|
274
|
+
|
275
|
+
class BandNotNull(Band, tablename="band"):
|
276
|
+
manager = ForeignKey(Manager, null=False)
|
277
|
+
|
278
|
+
|
279
|
+
class TestGetOrCreateNotNull(AsyncTableTest):
|
280
|
+
|
281
|
+
tables = [BandNotNull, Manager]
|
282
|
+
|
283
|
+
async def test_not_null(self):
|
284
|
+
"""
|
285
|
+
There was a bug where `get_or_create` would fail for columns with
|
286
|
+
`default=None` and `null=False`, even if the value for those columns
|
287
|
+
was specified in the where clause.
|
288
|
+
|
289
|
+
https://github.com/piccolo-orm/piccolo/issues/1152
|
290
|
+
|
291
|
+
"""
|
292
|
+
|
293
|
+
manager = Manager({Manager.name: "Test"})
|
294
|
+
await manager.save()
|
295
|
+
|
296
|
+
self.assertIsInstance(
|
297
|
+
await BandNotNull.objects().get_or_create(
|
298
|
+
BandNotNull.manager == manager
|
299
|
+
),
|
300
|
+
BandNotNull,
|
301
|
+
)
|
File without changes
|
File without changes
|