Basic Usage

To start using EdgeDB in Python, create an edgedb.Client instance using edgedb.create_client():

  1. import datetime
  2. import edgedb
  3. client = edgedb.create_client()
  4. client.query("""
  5. INSERT User {
  6. name := <str>$name,
  7. dob := <cal::local_date>$dob
  8. }
  9. """, name="Bob", dob=datetime.date(1984, 3, 1))
  10. user_set = client.query(
  11. "SELECT User {name, dob} FILTER .name = <str>$name", name="Bob")
  12. # *user_set* now contains
  13. # Set{Object{name := 'Bob', dob := datetime.date(1984, 3, 1)}}
  14. client.close()

When used with asyncio, this should be replaced with edgedb.create_async_client() which creates an instance of the AsyncIOClient:

  1. import asyncio
  2. import datetime
  3. import edgedb
  4. client = edgedb.create_async_client()
  5. async def main():
  6. await client.query("""
  7. INSERT User {
  8. name := <str>$name,
  9. dob := <cal::local_date>$dob
  10. }
  11. """, name="Bob", dob=datetime.date(1984, 3, 1))
  12. user_set = await client.query(
  13. "SELECT User {name, dob} FILTER .name = <str>$name", name="Bob")
  14. # *user_set* now contains
  15. # Set{Object{name := 'Bob', dob := datetime.date(1984, 3, 1)}}
  16. await client.aclose()
  17. asyncio.run(main())

Connect to EdgeDB

The examples above only work under an EdgeDB project. You could also provide your own connection parameters, refer to the Client Library Connection docs for details.

Type conversion

edgedb-python automatically converts EdgeDB types to the corresponding Python types and vice versa. See Datatypes for details.

Client connection pools

For server-type type applications that handle frequent requests and need the database connection for a short period time while handling a request, the use of a connection pool is recommended. Both edgedb.Client and edgedb.AsyncIOClient come with such a pool.

For edgedb.Client, all methods are thread-safe. You can share the same client instance safely across multiple threads, and run queries concurrently. Likewise, AsyncIOClient is designed to be shared among different asyncio.Task/coroutines for concurrency.

Below is an example of a web API server running aiohttp:

  1. import asyncio
  2. import edgedb
  3. from aiohttp import web
  4. async def handle(request):
  5. """Handle incoming requests."""
  6. client = request.app['client']
  7. username = int(request.match_info.get('name'))
  8. # Execute the query on any pool connection
  9. result = await client.query_single_json(
  10. '''
  11. SELECT User {first_name, email, bio}
  12. FILTER .name = <str>$username
  13. ''', username=username)
  14. return web.Response(
  15. text=result,
  16. content_type='application/json')
  17. def init_app():
  18. """Initialize the application server."""
  19. app = web.Application()
  20. # Create a database client
  21. app['client'] = edgedb.create_async_client(
  22. database='my_service',
  23. user='my_service')
  24. # Configure service routes
  25. app.router.add_route('GET', '/user/{name:\w+}', handle)
  26. return app
  27. loop = asyncio.get_event_loop()
  28. app = init_app()
  29. web.run_app(app)

Note that the client is created synchronously. Pool connections are created lazily as they are needed. If you want to explicitly connect to the database in init_app(), use the ensure_connected() method on the client.

For more information, see API documentation of the blocking client and the asynchronous client.

Transactions

The most robust way to create a transaction is the transaction() method:

Example:

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

or, if using the async API:

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

When not in an explicit transaction block, any changes to the database will be applied immediately.

For more information, see API documentation of transactions for the blocking client and the asynchronous client.