AsyncIO API​

Connection​

coroutine

async_connect()

AsyncIO API - 图1

async_connect(dsn = None, *, host = None, port = None, admin = None, user = None, password = None, database = None, timeout = 60)

Establish a connection to an EdgeDB server.

Deprecated. Use create_async_client() instead.

Example:

  1. >>>
  1. import asyncio
  1. >>>
  1. import edgedb
  1. >>>
  2. ...
  3. ...
  1. async def main():
  2. con = await edgedb.async_connect(user='edgedb')
  3. print(await con.query_single('SELECT 1 + 1'))
  1. ...
  1. >>>
  1. asyncio.run(main())
  1. {2}

Client connection pool​

function

create_async_client()

AsyncIO API - 图2

create_async_client(dsn = None, *, host = None, port = None, user = None, password = None, database = None, timeout = 60, concurrency = None)

Create an asynchronous lazy connection pool.

The connection parameters may be specified either as a connection URI in dsn, or as specific keyword arguments, or both. If both dsn and keyword arguments are specified, the latter override the corresponding values parsed from the connection URI.

Returns a new AsyncIOClient object.

Parameters

  • dsn (str) – If this parameter does not start with edgedb:// then this is interpreted as the name of a local instance.Otherwise it specifies a single string in the following format: edgedb://user:password@host:port/database?option=value. The following options are recognized: host, port, user, database, password. For a complete reference on DSN, see the DSN Specification.

  • host – Database host address as one of the following:

    • an IP address or a domain name;
    • an absolute path to the directory containing the database server Unix-domain socket (not supported on Windows);
    • a sequence of any of the above, in which case the addresses will be tried in order, and the first successful connection will be returned.

    If not specified, the following will be tried, in order:

    • host address(es) parsed from the dsn argument,
    • the value of the EDGEDB_HOST environment variable,
    • on Unix, common directories used for EdgeDB Unix-domain sockets: "/run/edgedb" and "/var/run/edgedb",
    • "localhost".
  • port – Port number to connect to at the server host (or Unix-domain socket file extension). If multiple host addresses were specified, this parameter may specify a sequence of port numbers of the same length as the host sequence, or it may specify a single port number to be used for all host addresses.If not specified, the value parsed from the dsn argument is used, or the value of the EDGEDB_PORT environment variable, or 5656 if neither is specified.

  • user – The name of the database role used for authentication.If not specified, the value parsed from the dsn argument is used, or the value of the EDGEDB_USER environment variable, or the operating system name of the user running the application.

  • database – The name of the database to connect to.If not specified, the value parsed from the dsn argument is used, or the value of the EDGEDB_DATABASE environment variable, or the operating system name of the user running the application.

  • password – Password to be used for authentication, if the server requires one. If not specified, the value parsed from the dsn argument is used, or the value of the EDGEDB_PASSWORD environment variable. Note that the use of the environment variable is discouraged as other users and applications may be able to read it without needing specific privileges.

  • timeout (float) – Connection timeout in seconds.

  • concurrency (int) – Max number of connections in the pool. If not set, the suggested concurrency value provided by the server is used.

Returns

An instance of AsyncIOClient.

The connection pool has high-level APIs to access Connection[link] APIs directly, without manually acquiring and releasing connections from the pool:

  1. client = edgedb.create_async_client(user='edgedb')
  2. await client.query('SELECT {1, 2, 3}')

Transactions can be executed as well:

  1. client = edgedb.create_async_client(user='edgedb')
  2. async for tx in client.transaction():
  3. async with tx:
  4. await tx.query('SELECT {1, 2, 3}')

class

AsyncIOClient

AsyncIO API - 图3

A connection pool.

A connection pool can be used in a similar manner as a single connection except that the pool is safe for concurrent use.

Pools are created by calling create_async_client().

coroutine

AsyncIOClient.query()

AsyncIO API - 图4

AsyncIOClient.query(query, * args, ** kwargs)

Acquire a connection and use it to run a query and return the results as an edgedb.Set instance. The temporary connection is automatically returned back to the pool.

Parameters

  • query (str) – Query text.

  • args – Positional query arguments.

  • kwargs – Named query arguments.

Returns

An instance of edgedb.Set containing the query result.

Note that positional and named query arguments cannot be mixed.

coroutine

AsyncIOClient.query_single()

AsyncIO API - 图5

AsyncIOClient.query_single(query, * args, ** kwargs)

Acquire a connection and use it to run an optional singleton-returning query and return its element. The temporary connection is automatically returned back to the pool.

Parameters

  • query (str) – Query text.

  • args – Positional query arguments.

  • kwargs – Named query arguments.

Returns

Query result.

The query must return no more than one element. If the query returns more than one element, an edgedb.ResultCardinalityMismatchError is raised, if it returns an empty set, None is returned.

Note, that positional and named query arguments cannot be mixed.

coroutine

AsyncIOClient.query_required_single()

AsyncIO API - 图6

AsyncIOClient.query_required_single(query, * args, ** kwargs)

Acquire a connection and use it to run a singleton-returning query and return its element. The temporary connection is automatically returned back to the pool.

Parameters

  • query (str) – Query text.

  • args – Positional query arguments.

  • kwargs – Named query arguments.

Returns

Query result.

The query must return exactly one element. If the query returns more than one element, an edgedb.ResultCardinalityMismatchError is raised, if it returns an empty set, an edgedb.NoDataError is raised.

Note, that positional and named query arguments cannot be mixed.

coroutine

AsyncIOClient.query_json()

AsyncIO API - 图7

AsyncIOClient.query_json(query, * args, ** kwargs)

Acquire a connection and use it to run a query and return the results as JSON. The temporary connection is automatically returned back to the pool.

Parameters

  • query (str) – Query text.

  • args – Positional query arguments.

  • kwargs – Named query arguments.

Returns

A JSON string containing an array of query results.

Note, that positional and named query arguments cannot be mixed.

Caution is advised when reading decimal values using this method. The JSON specification does not have a limit on significant digits, so a decimal number can be losslessly represented in JSON. However, the default JSON decoder in Python will read all such numbers as float values, which may result in errors or precision loss. If such loss is unacceptable, then consider casting the value into str and decoding it on the client side into a more appropriate type, such as Decimal.

coroutine

AsyncIOClient.query_single_json()

AsyncIO API - 图8

AsyncIOClient.query_single_json(query, * args, ** kwargs)

Acquire a connection and use it to run an optional singleton-returning query and return its element in JSON. The temporary connection is automatically returned back to the pool.

Parameters

  • query (str) – Query text.

  • args – Positional query arguments.

  • kwargs – Named query arguments.

Returns

Query result encoded in JSON.

The query must return no more than one element. If the query returns more than one element, an edgedb.ResultCardinalityMismatchError is raised, if it returns an empty set, "null" is returned.

Note, that positional and named query arguments cannot be mixed.

Caution is advised when reading decimal values using this method. The JSON specification does not have a limit on significant digits, so a decimal number can be losslessly represented in JSON. However, the default JSON decoder in Python will read all such numbers as float values, which may result in errors or precision loss. If such loss is unacceptable, then consider casting the value into str and decoding it on the client side into a more appropriate type, such as Decimal.

coroutine

AsyncIOClient.query_required_single_json()

AsyncIO API - 图9

AsyncIOClient.query_required_single_json(query, * args, ** kwargs)

Acquire a connection and use it to run a singleton-returning query and return its element in JSON. The temporary connection is automatically returned back to the pool.

Parameters

  • query (str) – Query text.

  • args – Positional query arguments.

  • kwargs – Named query arguments.

Returns

Query result encoded in JSON.

The query must return exactly one element. If the query returns more than one element, an edgedb.ResultCardinalityMismatchError is raised, if it returns an empty set, an edgedb.NoDataError is raised.

Note, that positional and named query arguments cannot be mixed.

Caution is advised when reading decimal values using this method. The JSON specification does not have a limit on significant digits, so a decimal number can be losslessly represented in JSON. However, the default JSON decoder in Python will read all such numbers as float values, which may result in errors or precision loss. If such loss is unacceptable, then consider casting the value into str and decoding it on the client side into a more appropriate type, such as Decimal.

coroutine

AsyncIOClient.execute()

AsyncIO API - 图10

AsyncIOClient.execute(query)

Acquire a connection and use it to execute an EdgeQL command (or commands). The temporary connection is automatically returned back to the pool.

Parameters

query (str) – Query text.

The commands must take no arguments.

Example:

  1. >>>
  2. ...
  3. ...
  4. ...
  5. ...
  6. ...
  7. ...
  1. await con.execute('''
  2. CREATE TYPE MyType {
  3. CREATE PROPERTY a -> int64
  4. };
  5. FOR x IN {100, 200, 300}
  6. UNION INSERT MyType { a := x };
  7. ''')

If the results of query are desired, query(), query_single() or query_required_single() should be used instead.

method

AsyncIOClient.transaction()

AsyncIO API - 图11

Open a retryable transaction loop.

This is the preferred method of initiating and running a database transaction in a robust fashion. The transaction() transaction loop will attempt to re-execute the transaction loop body if a transient error occurs, such as a network error or a transaction serialization error.

Returns an instance of AsyncIORetry.

See Transactions for more details.

Example:

  1. async for tx in con.transaction():
  2. async with tx:
  3. value = await tx.query_single("SELECT Counter.value")
  4. await tx.execute(
  5. "UPDATE Counter SET { value := <int64>$value }",
  6. value=value + 1,
  7. )

Note that we are executing queries on the tx object rather than on the original connection.

coroutine

AsyncIOClient.aclose()

AsyncIO API - 图12

Attempt to gracefully close all connections in the pool.

Wait until all pool connections are released, close them and shut down the pool. If any error (including cancellation) occurs in close() the pool will terminate by calling Client.terminate().

It is advisable to use asyncio.wait_for() to set a timeout.

method

AsyncIOClient.terminate()

AsyncIO API - 图13

Terminate all connections in the pool.

coroutine

AsyncIOClient.ensure_connected()

AsyncIO API - 图14

If the client does not yet have any open connections in its pool, attempts to open a connection, else returns immediately.

Since the client lazily creates new connections as needed (up to the configured concurrency limit), the first connection attempt will only occur when the first query is run on a client. ensureConnected can be useful to catch any errors resulting from connection mis-configuration by triggering the first connection attempt explicitly.

Transactions​

The most robust way to execute transactional code is to use the transaction() loop API:

  1. async for tx in client.transaction():
  2. async with tx:
  3. await tx.execute("INSERT User { name := 'Don' }")

Note that we execute queries on the tx object in the above example, rather than on the original connection pool client object.

The transaction() API guarantees that:

  1. Transactions are executed atomically;

  2. If a transaction is failed for any of the number of transient errors (i.e. a network failure or a concurrent update error), the transaction would be retried;

  3. If any other, non-retryable exception occurs, the transaction is rolled back, and the exception is propagated, immediately aborting the transaction() block.

The key implication of retrying transactions is that the entire nested code block can be re-run, including any non-querying Python code. Here is an example:

  1. async for tx in client.transaction():
  2. async with tx:
  3. user = await tx.query_single(
  4. "SELECT User { email } FILTER .login = <str>$login",
  5. login=login,
  6. )
  7. data = await httpclient.get(
  8. 'https://service.local/email_info',
  9. params=dict(email=user.email),
  10. )
  11. user = await tx.query_single('''
  12. UPDATE User FILTER .login = <str>$login
  13. SET { email_info := <json>$data}
  14. ''',
  15. login=login,
  16. data=data,
  17. )

In the above example, the execution of the HTTP request would be retried too. The core of the issue is that whenever transaction is interrupted user might have the email changed (as the result of concurrent transaction), so we have to redo all the work done.

Generally it’s recommended to not execute any long running code within the transaction unless absolutely necessary.

Transactions allocate expensive server resources and having too many concurrently running long-running transactions will negatively impact the performance of the DB server.

See also:

class

AsyncIORetry

AsyncIO API - 图15

Represents a wrapper that yields AsyncIOTransaction object when iterating.

See AsyncIOClient.transaction() method for an example.

coroutine

AsyncIORetry.__anext__()

AsyncIO API - 图16

Yields AsyncIOTransaction object every time transaction has to be repeated.

class

AsyncIOTransaction

AsyncIO API - 图17

Represents a transaction or a savepoint block.

Instances of this type are yielded by a :py:class`AsyncIORetry` iterator.

coroutine

AsyncIOTransaction.start()

AsyncIO API - 图18

Start a transaction or create a savepoint.

coroutine

AsyncIOTransaction.commit()

AsyncIO API - 图19

Exit the transaction or savepoint block and commit changes.

coroutine

AsyncIOTransaction.rollback()

AsyncIO API - 图20

Exit the transaction or savepoint block and discard changes.

interface

async with c:

AsyncIO API - 图21

Start and commit/rollback the transaction or savepoint block automatically when entering and exiting the code inside the context manager block.

coroutine

AsyncIOTransaction.query()

AsyncIO API - 图22

AsyncIOTransaction.query(query, * args, ** kwargs)

Acquire a connection and use it to run a query and return the results as an edgedb.Set instance. The temporary connection is automatically returned back to the pool.

See AsyncIOClient.query() for details.

coroutine

AsyncIOTransaction.query_single()

AsyncIO API - 图23

AsyncIOTransaction.query_single(query, * args, ** kwargs)

Acquire a connection and use it to run an optional singleton-returning query and return its element. The temporary connection is automatically returned back to the pool.

See AsyncIOClient.query_single() for details.

coroutine

AsyncIOTransaction.query_required_single()

AsyncIO API - 图24

AsyncIOTransaction.query_required_single(query, * args, ** kwargs)

Acquire a connection and use it to run a singleton-returning query and return its element. The temporary connection is automatically returned back to the pool.

See AsyncIOClient.query_required_single() for details.

coroutine

AsyncIOTransaction.query_json()

AsyncIO API - 图25

AsyncIOTransaction.query_json(query, * args, ** kwargs)

Acquire a connection and use it to run a query and return the results as JSON. The temporary connection is automatically returned back to the pool.

See AsyncIOClient.query_json() for details.

coroutine

AsyncIOTransaction.query_single_json()

AsyncIO API - 图26

AsyncIOTransaction.query_single_json(query, * args, ** kwargs)

Acquire a connection and use it to run an optional singleton-returning query and return its element in JSON. The temporary connection is automatically returned back to the pool.

See AsyncIOClient.query_single_json() for details.

coroutine

AsyncIOTransaction.query_required_single_json()

AsyncIO API - 图27

AsyncIOTransaction.query_required_single_json(query, * args, ** kwargs)

Acquire a connection and use it to run a singleton-returning query and return its element in JSON. The temporary connection is automatically returned back to the pool.

See AsyncIOClient.query_requried_single_json() for details.

coroutine

AsyncIOTransaction.execute()

AsyncIO API - 图28

AsyncIOTransaction.execute(query)

Acquire a connection and use it to execute an EdgeQL command (or commands). The temporary connection is automatically returned back to the pool.

See AsyncIOClient.execute() for details.