Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose an API for running QueryString #406

Open
dantownsend opened this issue Jan 25, 2022 · 1 comment
Open

Expose an API for running QueryString #406

dantownsend opened this issue Jan 25, 2022 · 1 comment
Labels
enhancement New feature or request

Comments

@dantownsend
Copy link
Member

dantownsend commented Jan 25, 2022

Piccolo uses a class called QueryString internally for composing queries. It's very powerful, and allows you to compose complex nested queries, and compiles to a parameterised SQL statement and values.

At the moment, if someone wants to compose their own query, they have to use raw. For example await Band.raw('some custom query').

As a middle ground, we should allow the user to compose their own queries using QueryString. This is currently possible, but it's undocumented, and the API isn't pretty.

For example, if we wanted to modify an INSERT query to add an ON CONFLICT clause:

from piccolo.querystring import QueryString

# Assuming `Manager` is your table class, and `some_unique_column` is a unique column name:
querystring = QueryString(
    "{} ON CONFLICT (some_unique_column) DO NOTHING",
    Manager.insert(Manager(name='Guido')).querystrings[0]
)
await Manager._meta.db.run_querystring(querystring)

We could directly expose a way of running QueryString, either by modifying Table.raw so it can accept a string or QueryString. Alternatively, we could add a new method (something like run_querystring).

from piccolo.querystring import QueryString

querystring = QueryString(
    "{} ON CONFLICT (some_unique_column) DO NOTHING",
    Manager.insert(Manager(name='Guido')) # We should allow a query to be passed in, and auto extract the querystring from it.
)
await Manager.run_querystring(querystring)

This will need documenting, possibly under the same section of the docs which covers raw queries.

Originally discussed in #403 and #405.

@dantownsend dantownsend added the enhancement New feature or request label Jan 25, 2022
@dantownsend dantownsend changed the title Expose an API for dealing with QueryString Expose an API for running QueryString Jan 25, 2022
@theelderbeever
Copy link
Contributor

I think it would be really helpful to be able to nest QueryString objects as well. This would make passing the parameters easier to construct as well and I think would help with making helper functions down the road. Right now if you do something like the following...

querystring = QueryString("INSERT INTO managers (name, salary, json_data)  VALUES ({},{},{})", "Bob", 100_000, '{"hello": "world"}')

querystring_w_conflict = QueryString("{} ON CONFLICT (name) DO NOTHING", querystring)

The second QueryString interpolation will turn the json data into '' a blank string.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants