asyncpg

Another library, asyncpg, does not implement Python's DB API. Instead it provides an asynchronous API that is supposed to be used with asyncio--a Python library used to write concurrent code. It is out of the scope of this book to learn asynchronous programming, so we will only provide and explain a couple of simplified examples.

As mentioned before, asynchronous execution implies firing a task and, while it is executing, doing something else. The asyncio.connect() function that is used to connect to the database is asynchronous. Functions that are used to execute queries or close the connection are also asynchronous.

There is a concept of callbacks in asynchronous programming. A callback function is a function that belongs to your application that is executed automatically when a certain event happens. Here is an example of using a callback function that reacts on messages from the database:

import asyncio
import asyncpg

async def main():
conn = await asyncpg.connect(host='localhost', user='car_portal_app',
database='car_portal')
conn.add_log_listener(lambda conn, msg: print(msg))
print("Executing a command")
await conn.execute('''DO $$ BEGIN RAISE NOTICE 'Hello'; END; $$;''')
print("Finished execution")
await conn.close()

asyncio.get_event_loop().run_until_complete(main())

If you are not familiar with asynchronous features of Python, to understand the preceding code, you need to know the following keywords and expressions:

  • async is used to indicate that the function defined after it is a coroutine, which means that it is asynchronous and should be executed in a special way.
  • await is used to execute coroutines synchronously. Basically, when a coroutine function is called with await statement, it is working as a normal function and the execution will continue only when the function returns.
  • lambda defines an inline function. In the preceding example, the expression lambda conn, msg: print(msg) defines a function with two parameters, conn and msg, that prints the value of msg. lambda expressions are not specific to asynchronous programming, but they are very convenient to use as simple callbacks.

The preceding script executes a piece of code in the database written in PL/pgSQL. This code is doing nothing but generating a NOTICE. This code is executed asynchronously in the database. Although the script waits for the function conn.execute() to finish, the callback function is triggered immediately when the NOTICE is raised. You may add some delays into the expression DO by calling the function pg_sleep() to see that. 

In the last line of the code sample, the function main() is invoked. The function is defined as a coroutine, that is why it is not possible to simply call it. In the example, the expression in the last line invokes the function and waits until it finishes.

More explicit examples are available in the enclosed code bundle in the file asyncpg_raise_notice.py

The benefit of using asyncpg over psycopg2 is performance. The developers of asyncpg claim that it is about three times faster than psycopg2. It does not require any PostgreSQL libraries present in the system. It is asynchronous, which makes it possible to develop very efficient applications. 

The drawback is that it is quite complicated to develop and debug asynchronous code. It does not comply to DB API 2.0 and for this reason, other libraries that use this database abstraction API could not use asyncpg. It is a relatively new software. There is not that much information or examples available yet.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset