edgedb-cli
edgedb-cli copied to clipboard
Support passing query parameters to query files
Hey!
Passing a script that contains parameters into the CLI will throw edgedb error: DescriptorMismatch: query arguments expected
.
And it appears that there is seemingly no option to pass them in.
I would prefer the command having some way of passing them in and/or having the option to get interactive prompts for them.
Command (and it's output)
# cat queries\test.edgeql | edgedb
edgedb error: DescriptorMismatch: query arguments expected
# edgedb query --file queries\test.edgeql
edgedb error: DescriptorMismatch: query arguments expected
Yes, we don't have a way currently. Can you describe your use case a bit more? I'm not sure whether asking interactively makes sense here. Or if we ask interactively whether memoizing variables with the same name across different queries is something expected.
I personally use the scripts mostly to do occasional seeding to my database, with the script taking in parameters to push different objects to the database.
I would agree that piping into EdgeDB should always imply non-interactive mode,
however I would've at least expected edgedb query --file
to prompt me for the variables interactively.
As for memoizing them across queries, I think that would be very unexpected; If you run a query with required parameters, you should always provide them.
create-user.edgeql
WITH
userName := <str>$userName,
userRoles := <array<str>>$roles,
INSERT User {
name := userName,
roles := (select UserRole filter .name in array_unpack(userRoles))
};
As for memoizing them across queries, I think that would be very unexpected; If you run a query with required parameters, you should always provide them.
I mean, in script like this:
INSERT User { name := <str>$userName };
INSERT Inventory { item := (SELECT User FILTER .name = <str>$userName)};
Do you expect userName
to be entered twice?
(well, technically this can be rewritten into a single query, but this can be less convenient for huge number of inserts)
As for memoizing them across queries, I think that would be very unexpected; If you run a query with required parameters, you should always provide them.
I mean, in script like this:
INSERT User { name := <str>$userName }; INSERT Inventory { item := (SELECT User FILTER .name = <str>$userName)};
Do you expect
userName
to be entered twice? (well, technically this can be rewritten into a single query, but this can be less convenient for huge number of inserts)
Oh, my bad. This is an interesting question, my instincts say that it should only have to be entered once since it shares the same query parameter name.
And I believe it should follow the same semantics as the REPL and the clients that interact with EdgeDB, I believe all of them provide one value per query parameter key/name.
Here's the REPL that only asks for it once:
edgedb> WITH
....... username := <str>$username
....... SELECT {
....... user1 := username,
....... user2 := <str>$username
....... };
Parse: 98.7067ms
Parameter <str>$username: test
{{user1: 'test', user2: 'test'}}
Oh, I actually need this. In my case, I use separate files for queries that I later read from my backend code. During development, I want to test the queries before writing any code.
I'll just leave this here:
#!/bin/bash
(( $# < 1 )) && echo "Usage: $0 <query-file> [...query-args]" && exit 1
query_file=$1
shift;
readarray -t found_tokens < <(grep -Po '>\K\$[\w_]+' -- "$query_file")
declare -A query_args
for arg in "${found_tokens[@]}"; do
[[ -v query_args[$arg] ]] && continue
value=$1
if shift; then
query_args[$arg]=$value
else
read -rp "Enter value for $arg: " value
query_args[$arg]=$value
fi
done
sed_args=()
for arg in "${!query_args[@]}"; do
sed_args+=(-e "s/\\$arg/${query_args[$arg]}/g")
done
edgedb query --file <(sed "${sed_args[@]}" -- "$query_file")
It will ask interactively for args. Moreover, you can also provide the args (in the order of appearance in the file) on the command line, and this way you can easily rerun the query with the same args without having to type them in.
+1 The CLI is a convenient way to quickly run a query from a file without having to copy and paste around in some UI or mock a client in code.