You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
High-level API provides a single point for all async ORM calls. Meet the :class:`.Manager` class! The idea of ``Manager`` originally comes from `Django`_, but it's redesigned to meet new `asyncio`_ patterns.
5
-
6
-
First of all, once ``Manager`` is initialized with database and event loop, it's easy and safe to perform async calls. And all async operations and transactions management methods are bundled with a single object. No need to pass around database instance, event loop, etc.
7
-
8
-
Also there's no need to connect and re-connect before executing async queries with manager! It's all automatic. But you can run ``Manager.connect()`` or ``Manager.close()`` when you need it.
-- once ``objects`` is created with specified ``loop``, all database connections **automatically** will be set up on **that loop**. Sometimes, it's so easy to forget to pass custom loop instance, but now it's not a problem! Just initialize with an event loop once.
-- as you can see, nothing special in this code, just plain ``peewee_async.AioModel`` definition.
24
+
-- as you can see, nothing special in this code, just plain ``peewee_async.AioModel`` definition and disabling sync queries.
37
25
38
26
Now we need to create a table for model::
39
27
40
-
PageBlock.create_table(True)
28
+
with database.allow_sync():
29
+
PageBlock.create_table(True)
41
30
42
31
-- this code is **sync**, and will do **absolutely the same thing** as would do code with regular ``peewee.PostgresqlDatabase``. This is intentional, I believe there's just no need to run database initialization code asynchronously! *Less code, less errors*.
43
32
@@ -56,75 +45,43 @@ Finally, let's do something async::
56
45
57
46
# Save with new text using manager
58
47
title.text = "Peewee is SUPER awesome with async!"
59
-
await objects.update(title)
48
+
await title.aio_save()
60
49
print("New:", title.text)
61
50
62
51
loop.run_until_complete(my_async_func())
63
52
loop.close()
64
53
65
-
**That's it!**
54
+
**That's it!** As you may notice there's no need to connect and re-connect before executing async queries! It's all automatic. But you can run ``AioDatabase.aio_connect()`` or ``AioDatabase.aio_close()`` when you need it.
66
55
67
-
As you may notice you can use methods from **Manager** or from **AioModel** for operations like selecting, deleting etc.
56
+
And you can use methods from from **AioModel** for operations like selecting, deleting etc.
`Tornado`_ is a mature and powerful asynchronous web framework. It provides its own event loop, but there's an option to run Tornado on asyncio event loop. And that's exactly what we need!
72
+
73
+
.. _Tornado: http://www.tornadoweb.org
74
+
75
+
The complete working example is provided below. And here are some general notes:
76
+
77
+
1. **Be aware of current asyncio event loop!**
78
+
79
+
In the provided example we use the default event loop everywhere, and that's OK. But if you see your application got silently stuck, that's most probably that some task is started on the different loop and will never complete as long as that loop is not running.
The ``CreateHandler`` demostrates that, ``current_task()`` returns ``None`` until task is run explicitly.
84
+
85
+
3. Transactions **must** run within task context.
86
+
87
+
All transaction operations have to be done within task. So if you need to run a transaction from Tornado handler, you have to wrap your call into task with ``create_task()`` or ``ensure_future()``.
88
+
89
+
**Also note:** if you spawn an extra task during a transaction, it will run outside of that transaction.
0 commit comments