Bug? LOAD CSV WITH HEADERS not working when called through REST?

943 views
Skip to first unread message

Daniel Corbett

unread,
Sep 18, 2014, 1:39:32 PM9/18/14
to ne...@googlegroups.com
If the LOAD CSV syntax is valid, then I get a weird response -- JSON with both empty result and empty error arrays.   I reported it on Stacked Overflow ( http://stackoverflow.com/questions/25901283/sending-cypher-script-with-load-csv-via-rest-isnt-working-for-me ), but the response has been focused on syntax unrelated to the fundamental question.

When called within REST the query

LOAD CSV WITH HEADERS FROM 'xx file://C:/countries.csvxxx' as csvLine
MERGE (c:Country { Code: csvLine.Code })

gives me:

{
  • results: [ ],
  • errors: [ ]
}

But this is clearly an error.  Putting a valid File: or Http bath also has the same response.   However.   For example this  query with my CSV REST service works fine in the Neo4j browser, but not when sent through REST.  ( gives the same response as above, without actually performing the merge ).

LOAD CSV WITH HEADERS FROM 'http://localhost:9000/api/csv/Countries/csv' as csvLine
MERGE (c:Country { Code: csvLine.Code })

The query:

LOAD CSV WITH HEADERS FROM 'file://C:/countries.csvxxx' as csvLine

produces an appropriate error:
{
  • results: [ ],
  • errors
    [
    • {
      • code"Neo.ClientError.Statement.InvalidSyntax",
      • message"Query cannot conclude with LOAD CSV (must be RETURN or an update clause) (line 1, column 67) "LOAD CSV WITH HEADERS FROM 'file://C:/countries.csvxxx' as csvLine" ^"
      }
    ]
}

Does anyone have an example of LOAD CSV through REST that works in 2.1.4?

I'm using the most recently release:  2.1.4

Thanks,

   - Daniel

Daniel Corbett

unread,
Sep 18, 2014, 2:02:08 PM9/18/14
to ne...@googlegroups.com

To add more information:

I'm doing this using WebAPI from a C# application.   It seems to work fine for any valid cypher query that doesn't include LOAD CSV as a part of it.

I'm calling it using "localhost:7474/db/data/transaction/commit" so it should commit within the one call.

For example the JSON package here produces the result below just fine.

{"statements":[{"statement":"CREATE (n { name : 'Andres', title : 'Developer' }) RETURN n;"}]}

---------------------------------------- {"results":[{"columns":["n"],"data":[{"row":[{"name":"Andres","title":"Developer"}]}]}],"errors":[]}


Daniel Corbett

unread,
Sep 19, 2014, 10:14:11 AM9/19/14
to ne...@googlegroups.com
Continuing to try things...    I am now using "Advanced REST Client" - a chrome application.   I am using the example from the LOAD CSV Documentation, along with the REST transaction commit example.

Here is a screen shot, showing my settings for the REST call, along with the payload and the result:


Here is a screen shot of me using the same tool & settings with a simple Cypher script that works:


I've tried so many things...  this seems to be a bug.

Help please!

Thanks,

   - Daniel

Lasse Westh-Nielsen

unread,
Sep 19, 2014, 10:38:49 AM9/19/14
to Neo4j User
Daniel,

Try adding a return statement. The load csv example doesn;t have a return statement.

I can;t rule out that the browser tries to be extra user friendly and adds some helpful return statement for you...

If you do load csv and then inspect the database with a regular query, do you see the data you expect in there?

 - Lasse



--
You received this message because you are subscribed to the Google Groups "Neo4j" group.
To unsubscribe from this group and stop receiving emails from it, send an email to neo4j+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Join us at GraphConnect 2014 SF! graphconnect.com
As a friend of Neo4j, use discount code *KOMPIS* for $100 off registration

Michael Hunger

unread,
Sep 19, 2014, 10:40:06 AM9/19/14
to ne...@googlegroups.com
Hi Daniel, seems to depend on the escaping of the quotes but definitely weird.
It's afaik not related to Cypher but the streaming JSON parser before it. I think it somehow concludes that it parsed the input correctly but without any output

e.g. here I get the same as you

curl -XPOST -i -H accept:application/json -H content-type:application/json -d '{"statements":[{"statement":"LOAD CSV WITH HEADERS F\"xx file://C:/countries.csvxxx\\" as csvLine MERGE (c:Country { Code: csvLine.Code })"}]}' http://localhost:7474/db/data/transaction/commit

HTTP/1.1 200 OK

Content-Type: application/json

Access-Control-Allow-Origin: *

Transfer-Encoding: chunked

Server: Jetty(9.0.5.v20130815)


{"results":[],"errors":[]}

and here it fails correctly

curl -XPOST -i -H accept:application/json -H content-type:application/json -d '{"statements":[{"statement":"LOAD CSV WITH HEADERS FROM \"xx file://C:/countries.csvxxx\" as csvLine MERGE (c:Country { Code: csvLine.Code })"}]}' http://localhost:7474/db/data/transaction/commit

HTTP/1.1 200 OK

Content-Type: application/json

Access-Control-Allow-Origin: *

Transfer-Encoding: chunked

Server: Jetty(9.0.5.v20130815)


{"results":[],"errors":[{"code":"Neo.TransientError.Statement.ExternalResourceFailure","message":"Invalid URL specified (no protocol: xx file://C:/countries.csvxxx)","stackTrace":"org.neo4j.cypher.LoadExternalResourceException: Invalid URL specified (no protocol: xx file://C:/countries.csvxxx)\n\tat org.neo4j.cypher.internal.compiler.v2_1.pipes.LoadCSVPipe.checkURL(LoadCSVPipe.scala:50)\n\tat org.neo4j.cypher.internal.compiler.v2_1.pipes.LoadCSVPipe$$anonfun$internalCreateResults$1.apply(LoadCSVPipe.scala:66)\n\tat org.neo4j.cypher.internal.compiler.v2_1.pipes.LoadCSVPipe$$anonfun$internalCreateResults$1.apply(LoadCSVPipe.scala:64)\n\tat scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)\n\tat scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)\n\tat org.neo4j.cypher.internal.compiler.v2_1.pipes.EmptyResultPipe.internalCreateResults(EmptyResultPipe.scala:29)\n\tat org.neo4j.cypher.internal.compiler.v2_1.pipes.PipeWithSource.createResults(Pipe.scala:105)\n\tat org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1$$anonfun$apply$2.apply(ExecutionPlanBuilder.scala:120)\n\tat org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1$$anonfun$apply$2.apply(ExecutionPlanBuilder.scala:119)\n\tat org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionWorkflowBuilder.runWithQueryState(ExecutionPlanBuilder.scala:168)\n\tat org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1.apply(ExecutionPlanBuilder.scala:118)\n\tat org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1.apply(ExecutionPlanBuilder.scala:103)\n\tat org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anon$1.execute(ExecutionPlanBuilder.scala:68)\n\tat org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anon$1.execute(ExecutionPlanBuilder.scala:67)\n\tat org.neo4j.cypher.internal.ExecutionPlanWrapperForV2_1.execute(CypherCompiler.scala:159)\n\tat org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:76)\n\tat org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:71)\n\tat org.neo4j.cypher.javacompat.ExecutionEngine.execute(ExecutionEngine.java:84)\n\tat org.neo4j.server.rest.transactional.TransactionHandle.executeStatements(TransactionHandle.java:277)\n\tat org.neo4j.server.rest.transactional.TransactionHandle.commit(TransactionHandle.java:139)\n\tat org.neo4j.server.rest.web.TransactionalService$2.write(TransactionalService.java:194)\n\tat com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:71)\n\tat com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:57)\n\tat com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306)\n\tat com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437)\n\tat com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)\n\tat com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)\n\tat com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)\n\tat com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)\n\tat com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)\n\tat javax.servlet.http.HttpServlet.service(HttpServlet.java:848)\n\tat org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:698)\n\tat org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:505)\n\tat org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:211)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1096)\n\tat org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:432)\n\tat org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:175)\n\tat org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1030)\n\tat org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:136)\n\tat org.eclipse.jetty.server.handler.HandlerList.handle(HandlerList.java:52)\n\tat org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)\n\tat org.eclipse.jetty.server.Server.handle(Server.java:445)\n\tat org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:268)\n\tat org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:229)\n\tat org.eclipse.jetty.io.AbstractConnection$ReadCallback.run(AbstractConnection.java:358)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:601)\n\tat org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:532)\n\tat java.lang.Thread.run(Thread.java:744)\n"}]}





On Fri, Sep 19, 2014 at 4:14 PM, Daniel Corbett <dani...@gmail.com> wrote:

Michael Hunger

unread,
Sep 19, 2014, 10:42:29 AM9/19/14
to ne...@googlegroups.com
So please check the quotes you use around the URL, I had to double escape them. Or you use single quotes w/o escaping.

Michael Hunger

unread,
Sep 19, 2014, 10:56:09 AM9/19/14
to ne...@googlegroups.com
Lasse, the problem is that the statement doesn't break even if you pass an erroneous URL which normally causes Cypher to report an error.

Daniel C

unread,
Sep 19, 2014, 12:12:47 PM9/19/14
to ne...@googlegroups.com
Thanks for the help,

nawroth suggested that this is because there are new lines inside the Cypher statement which is in quotes.   My subsequent testing demonstrates that is true.  The REST JSON parser probably terminates when it hits a newline.   The other examples I tried before that worked were single line.   The one REST example that's more complex had a bunch of cypher phrases without newline separators in a single set of quotes.    This behavior could be made more clear in the documentation.



--
You received this message because you are subscribed to a topic in the Google Groups "Neo4j" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/neo4j/802M8hYF1as/unsubscribe.
To unsubscribe from this group and all its topics, send an email to neo4j+un...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages