Hello i'm new to RethinkDB and facing issue with join query.Whenever I run my query it gives following error:
SyntaxError: missing ) after argument list
Following is my query:
r.db("test")
.table("posts")
.innerJoin(
r.db("test")
.table("user")
.filter({
"username": "super_admin"
}),
lambda posts,
user: posts["user_id"] == user["id"]
)
.zip()
It looks like you are trying to run Python code in a JavaScript interpreter.
The equivalent JavaScript code might be:
r.db("test").table("posts").innerJoin(
r.db("test").table("user").filter({
"username": "super_admin"
}),function(posts, user){
return posts("user_id").eq(user("id"))
}).zip()
As a side note, the query could be optimized by using eqJoin instead of innerJoin and perhaps also by using an index instead of a filter.
Put one semicolon ; after zip();
Related
I created a Variable (from Airflow UI):
Key: env_variables
Value: {'xx': 'yy`}
and trying to access using var.json.env_variables.xx inside bash operator. But the value of "xx" is dynamic, which
I am passing from REST API and accessing it using dag_run.conf['param'] (dag_run.conf['param'] should return xx). Eventually I want to run var.json.env_variables.xx. How can I achieve that inside bash operator in Airflow?
I am trying to run the following code but its showing Jinja Syntax Error.
task = BashOperator(
bash_command="export KUBECONFIG=$KUBECONFIG:{{var.json.env_variables.{{dag_run.conf['param']}} }}
What I want:
It should fetch the value of var.json.env_variables.xx. I have also tried using params but no luck, params.path is returning None.
task = BashOperator(
bash_command="export KUBECONFIG=$KUBECONFIG:{{params.path}},
params: {
"path":env_variables.get('{{dag_run.conf["param"]}}')
}
Any kind of help is highly appreciated.
You don't need the extra {{...}} in the Jinja expression around dag_run.conf and you'll also need the typical item access of a dictionary. Try using a template expression like this:
nested_vars = BashOperator(
task_id="nest_vars",
bash_command="export KUBECONFIG=$KUBECONFIG:{{ var.json.env_variables[dag_run.conf['param']] }}"
)
This is the log entry when passing in a triggering config of {"param": "xx"} to the operator instantiation above:
INFO - Running command: ['bash', '-c', 'export KUBECONFIG=$KUBECONFIG:yy']
I want to call apoc procedure from the golang driver. I can fire basic cypher queries from the driver but while calling apoc procedure it throws a syntax error.
panic: An error occurred getting result of exec command: messages.FailureMessage{Metadata:map[string]interface {}{"code":"Neo.ClientError.Statement.SyntaxError", "message":"Invalid input '3': expected whitespace, '.', node labels, '[', \"=~\", IN, STARTS, ENDS, CONTAINS, IS, '^', '*', '/', '%', '+', '-', '=', '~', \"<>\", \"!=\", '<', '>', \"<=\", \">=\", AND, XOR, OR, ',' or ')' (line 1, column 74 (offset: 73))\n\"call apoc.export.json.query(\"MATCH t = (p)-[:has*0..] -> (i:node{name:\"39\"}) return p;\",\"2.json\")\"\n
call apoc.export.json.query("MATCH t = (p)-[:has*0..] -> (i:node{name:"39"}) return p;","1.json")
I want to fire the above query from golang. Basically, golang wants me to pass the query as a string. Here the query itself contains a nested string in it. I think the error is due to that. Below is the syntax I am using to query from golang.
conn.PrepareNeo("call apoc.export.json.query(\"MATCH t = (p)-[:has*0..] -> (i:node{name:\"39\"}) return p;\",\"1.json\"")
You're right about the trouble, I think. I'd start at the other end of this and work backwards. The query you want to issue (and what you'd type in the Neo4j Browser) is:
call apoc.export.json.query("MATCH t = (p)-[:has*0..]->(i:node {name: \"39\"}) return p;", "1.json")
vs what Neo4j claims you actually sent:
call apoc.export.json.query("MATCH t = (p)-[:has*0..] -> (i:node{name:"39"}) return p;","1.json")
Notice that we've not got any backslashes escaping the quotes around "39" in the Go-generated query.
To fix, we need to emit the backslashes explicitly - I'm not a Go developer so there might be a tidier way of doing this, but in other languages it would be something like:
conn.PrepareNeo("call apoc.export.json.query(\"MATCH t = (p)-[:has*0..]->(i:node {name: \\\"39\\\"}) return p;\", \"1.json\")")
Or use a raw string literal (again, not a Go developer so not certain on this one):
conn.PrepareNeo(`call apoc.export.json.query("MATCH t = (p)-[:has*0..]->(i:node {name: \"39\"}) return p;", "1.json")`)
First time using pg gem to access postgres database. I've connected successfully and can run queries using #exec, but now building a simple query with #exec_params does not seem to be replacing parameters. I.e:
get '/databases/:db/tables/:table' do |db_name, table_name|
conn = connect(db_name)
query_result = conn.exec_params("SELECT * FROM $1;", [table_name])
end
results in #<PG::SyntaxError: ERROR: syntax error at or near "$1" LINE 1: SELECT * FROM $1; ^ >
This seems like such a simple example to get working - am I fundamentally misunderstanding how to use this method?
You can use placeholders for values, not for identifiers (such as table and column names). This is the one place where you're stuck using string interpolation to build your SQL. Of course, if you're using string wrangling for your SQL, you must be sure to properly quote/escape things; for identifiers, that means using quote_ident:
+ (Object) quote_ident(str)
Returns a string that is safe for inclusion in a SQL query as an identifier. Note: this is not a quote function for values, but for identifiers.
So you'd say something like:
table_name = conn.quote_ident(table_name)
query_result = conn.exec("SELECT * FROM #{table_name}")
I really like how the error messages include a text string representing what the ReQL code looks like. Is it possible to get at this without forcing an error?
Example Error message:
RqlRuntimeError: No attribute `colors` in object:
{...}
in:
r.db("r_g").table("items").group("collection").ungroup().map(function(var_0) { return var_0("group").object(var_0("reduction")); }).concatMap(function(var_1) { return var_1("colors"); })
I'm wanting to get at the value after "in:" shown before I run() the query.
You can use .toString() like query.toString() (without .run(...))
It should use the same code as the one used to generate backtraces.
I opened an issue this morning to add it in the docs, it is somehow missing -- https://github.com/rethinkdb/docs/issues/354
I am using Rethinkdb 1.10.1 with the official python driver. I have a table of tagged things which are associated to one user:
{
"id": "PK",
"user_id": "USER_PK",
"tags": ["list", "of", "strings"],
// Other fields...
}
I want to query by user_id and tag (say, to find all the things by user "tawmas" with tag "tag"). Starting with Rethinkdb 1.10 I can create a multi-index like this:
r.table('things').index_create('tags', multi=True).run(conn)
My query would then be:
res = (r.table('things')
.get_all('TAG', index='tags')
.filter(r.row['user_id'] == 'USER_PK').run(conn))
However, this query still needs to scan all the documents with the given tag, so I would like to create a compound index based on the user_id and tags fields. Such an index would allow me to query with:
res = r.table('things').get_all(['USER_PK', 'TAG'], index='user_tags').run(conn)
There is nothing in the documentation about compound multi-indexes. However, I
tried to use a custom index function combining the requirements for compound
indexes and multi-indexes by returning a list of ["USER_PK", "tag"] pairs.
My first attempt was in python:
r.table('things').index_create(
'user_tags',
lambda each: [[each['user_id'], tag] for tag in each['tags']],
multi=True).run(conn)
This makes the python driver choke with a MemoryError trying to parse the index function (I guess list comprehensions aren't really supported by the driver).
So, I turned to my (admittedly, rusty) javascript and came up with this:
r.table('things').index_create(
'user_tags',
r.js(
"""(function (each) {
var result = [];
var user_id = each["user_id"];
var tags = each["tags"];
for (var i = 0; i < tags.length; i++) {
result.push([user_id, tags[i]]);
}
return result;
})
"""),
multi=True).run(conn)
This is rejected by the server with a curious exception: rethinkdb.errors.RqlRuntimeError: Could not prove function deterministic. Index functions must be deterministic.
So, what is the correct way to define a compound multi-index? Or is it something
which is not supported at this time?
Short answer:
List comprehensions don't work in ReQL functions. You need to use map instead like so:
r.table('things').index_create(
'user_tags',
lambda each: each["tags"].map(lambda tag: [each['user_id'], tag]),
multi=True).run(conn)
Long answer
This is actually a somewhat subtle aspect of how RethinkDB drivers work. So the reason this doesn't work is that your python code doesn't actually see real copies of the each document. So in the expression:
lambda each: [[each['user_id'], tag] for tag in each['tags']]
each isn't ever bound to an actual document from your database, it's bound to a special python variable which represents the document. I'd actually try running the following just to demonstrate it:
q = r.table('things').index_create(
'user_tags',
lambda each: print(each)) #only works in python 3
And it will print out something like:
<RqlQuery instance: var_1 >
the driver only knows that this is a variable from the function, in particular it has no idea if each["tags"] is an array or what (it's actually just another very similar abstract object). So python doesn't know how to iterate over that field. Basically exactly the same problem exists in javascript.