edgedb / edgedb-python

The official Python client library for EdgeDB
https://edgedb.com
Apache License 2.0
366 stars 43 forks source link

Create query builder like the Typescript client library has #292

Open jerber opened 2 years ago

jerber commented 2 years ago

The TS client library has a very cool auto-generated query builder. With python typing we could build the same type of functionality. Here is the TS docs: https://www.edgedb.com/docs/clients/01_js/generation

nandorojo commented 2 years ago

Would love to have this for Python.

fantix commented 2 years ago

Yes, this is absolutely part of the plan. Let's keep this issue open until it's implemented.

Pentusha commented 2 years ago

You may be interested in a project that I made over a couple of weekends. The current features set can be best seen in documentation. I tried to make it look like SQLAlchemy Core and not like TypeScript builder. I think this might be a good starting point. It allows you to build complex expressions:

from edgeql_qb import EdgeDBModel
from edgeql_qb.operators import Alias
from edgeql_qb.types import int16

# please note that you may specify module for model,
# which would be used in every generated `with` statements.
Person = EdgeDBModel('Person', module='imdb')
Movie = EdgeDBModel('Movie', module='imdb')

actors = Person.insert.values(first_name='Harrison', last_name='Ford').label('actors')
director = Person.select().where(Person.c.id == director_id).limit1.label('director')
title = Alias('title').assign('Blade Runner 2049')
year = Alias('year').assign(int16(2017))
query = Movie.insert.with_(actors, director, title, year).values(
    title=title,
    year=year,
    director=director,
    actors=actors,
).build()

print(query.query)
# with
#     module imdb,
#     actors := (with imdb insert Person { first_name := <str>$insert_0, last_name := <str>$insert_1 }),
#     director := (with imdb select Person filter .id = $filter_2 limit 1),
#     title := <str>$with_3,
#     year := <int16>$with_4
# insert Movie {
#     title := title,
#     year := year,
#     director := director,
#     actors := actors
# }

print(query.context)
# {'insert_0': 'Harrison', 'insert_1': 'Ford', 'filter_2': director_id, 'with_3': 'Blade Runner 2049', 'with_4': 2017}

Any feedback is appreciated

rmzr7 commented 1 year ago

@fantix do you have an estimated timeline for this?

fantix commented 1 year ago

@fantix do you have an estimated timeline for this?

This has been discussed with the team again this week. It's likely that we'll soon come up with something that works in a similar way across Go and Python, so let's sit tight 😼

hwmrocker commented 1 year ago

This feature was just released, or are you talking about something different?

chrisemke commented 1 year ago

is there any news about this? should I use pentusha's project until it officially launches?

fantix commented 1 year ago

The codegen will likely be the main way to use for at least the Python binding, this is also demonstrated in the 3.0 launch event.

raddevon commented 9 months ago

Do you mind to create a separate feature request for this, @triumph1? I don't want it to get lost in this query builder request. It's slightly different and might be more feasible. (Don't know that it is but maybe.)

triumph1 commented 9 months ago

Sure! I'll make an issue and delete above comment. Thank you! 🙇‍♂️

triumph1 commented 9 months ago

Do you mind to create a separate feature request for this, @triumph1? I don't want it to get lost in this query builder request. It's slightly different and might be more feasible. (Don't know that it is but maybe.)

https://github.com/edgedb/edgedb-python/issues/463 done! 👍