Explorar el Código

Aiohttp switch to orjson (#9767)

* Aiohttp switch to orjson

* ensure that update runs over unique ids
Sergey Kovalev hace 4 meses
padre
commit
dc369c8148

+ 28 - 16
frameworks/Python/aiohttp/app/views.py

@@ -1,12 +1,12 @@
-from functools import partial
 from operator import attrgetter, itemgetter
 from pathlib import Path
-from random import randint
+from random import randint, sample
 
 import jinja2
-import ujson
-from aiohttp.web import Response, json_response
+import orjson
+from aiohttp.web import Response
 from sqlalchemy import select
+from sqlalchemy.orm.attributes import flag_modified
 
 from .models import sa_fortunes, sa_worlds, Fortune, World
 
@@ -16,7 +16,6 @@ READ_ROW_SQL = 'SELECT "randomnumber", "id" FROM "world" WHERE id = $1'
 READ_SELECT_ORM = select(World.randomnumber)
 WRITE_ROW_SQL = 'UPDATE "world" SET "randomnumber"=$2 WHERE id=$1'
 
-json_response = partial(json_response, dumps=ujson.dumps)
 template_path = Path(__file__).parent / 'templates' / 'fortune.jinja'
 template = jinja2.Template(template_path.read_text())
 sort_fortunes_orm = attrgetter('message')
@@ -34,6 +33,11 @@ def get_num_queries(request):
         return 500
     return num_queries
 
+def json_response(payload):
+    return Response(
+        body=orjson.dumps(payload),
+        content_type="application/json",
+    )
 
 async def json(request):
     """
@@ -74,7 +78,7 @@ async def multiple_database_queries_orm(request):
     result = []
     async with request.app['db_session']() as sess:
         for id_ in ids:
-            num = await sess.scalar(READ_SELECT_ORM.filter_by(id=id_))
+            num = await sess.scalar(READ_SELECT_ORM.where(World.id == id_))
             result.append({'id': id_, 'randomNumber': num})
     return json_response(result)
 
@@ -128,14 +132,21 @@ async def updates(request):
     Test 5 ORM
     """
     num_queries = get_num_queries(request)
-    updates = [(randint(1, 10000), randint(1, 10000)) for _ in range(num_queries)]
-    updates.sort()
-    worlds = [{'id': row_id, 'randomNumber': number} for row_id, number in updates]
+
+    ids = sample(range(1, 10000 + 1), num_queries)
+    ids.sort()
+    worlds = []
 
     async with request.app['db_session'].begin() as sess:
-        for id_, number in updates:
-            world = await sess.get(World, id_, populate_existing=True)
-            world.randomnumber = number
+        for row_id in ids:
+            random_number =  randint(1, 10000)
+            world = await sess.get(World, row_id, populate_existing=True)
+            world.randomnumber = random_number
+            # force sqlalchemy to UPDATE entry even if the value has not changed
+            # doesn't make sense in a real application, added only for pass `tfb verify`
+            flag_modified(world, "randomnumber")
+            worlds.append({'id': row_id, 'randomNumber': random_number})
+
     return json_response(worlds)
 
 async def updates_raw(request):
@@ -143,15 +154,16 @@ async def updates_raw(request):
     Test 5 RAW
     """
     num_queries = get_num_queries(request)
-    updates = [(randint(1, 10000), randint(1, 10000)) for _ in range(num_queries)]
-    updates.sort()
+    ids = sample(range(1, 10000 + 1), num_queries)
+    ids.sort()
+    updates = [(row_id, randint(1, 10000)) for row_id in ids]
     worlds = [{'id': row_id, 'randomNumber': number} for row_id, number in updates]
 
     async with request.app['pg'].acquire() as conn:
         stmt = await conn.prepare(READ_ROW_SQL)
-        for id_, _ in updates:
+        for row_id in ids:
             # the result of this is the int previous random number which we don't actually use
-            await stmt.fetchval(id_)
+            await stmt.fetchval(row_id)
         await conn.executemany(WRITE_ROW_SQL, updates)
 
     return json_response(worlds)

+ 3 - 4
frameworks/Python/aiohttp/requirements.txt

@@ -1,8 +1,7 @@
-aiohttp==3.11.14
+aiohttp==3.11.16
 asyncpg==0.30.0
 gunicorn==23.0.0
-jinja2==3.1.5
-psycopg2==2.9.10
+jinja2==3.1.6
 SQLAlchemy==2.0.39
-ujson==5.10.0
+orjson==3.10.16
 uvloop==0.21.0