cubiql icon indicating copy to clipboard operation
cubiql copied to clipboard

No implementation of method: :transform-result of protocol: #'graphql-qb.schema/ResultTransform found for class: graphql_qb.types.EnumType

Open agustingp opened this issue 6 years ago • 12 comments

Data converted following the instructions at https://github.com/Swirrl/graphql-qb/blob/master/doc/table2qb-cubiql.md is producing an "Internal server error: exception" when retrieving the observations with the query :

{cubiql{ dataset_iwavebnetworkzerocrossing{ observations{ page(first: 2000){ observation{ station_id latitude havg } } } } }}

Find attached the CSVs and ttl files resulting from the conversion zerocrossing_ttl.zip

In the logs file the error is:

clojure.lang.ExceptionInfo: java.lang.IllegalArgumentException in Interceptor :com.walmartlabs.lacinia.pedestal/query-executor - No implementation of method: :transform-result of protocol: #'graphql-qb.schema/ResultTransform found for class: graphql_qb.types.EnumType at clojure.core$ex_info.invokeStatic(core.clj:4739) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.core$ex_info.invoke(core.clj:4739) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$throwable__GT_ex_info.invokeStatic(chain.clj:35) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$throwable__GT_ex_info.invoke(chain.clj:32) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$try_f.invokeStatic(chain.clj:57) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$try_f.invoke(chain.clj:44) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all_with_binding.invokeStatic(chain.clj:171) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all_with_binding.invoke(chain.clj:146) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all$fn__15853.invoke(chain.clj:188) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.lang.AFn.applyToHelper(AFn.java:152) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.lang.AFn.applyTo(AFn.java:144) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.core$apply.invokeStatic(core.clj:657) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.core$with_bindings_STAR_.invokeStatic(core.clj:1965) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.core$with_bindings_STAR_.doInvoke(core.clj:1965) ~[graphql-qb-0.4.0-standalone.jar:?] at clojure.lang.RestFn.invoke(RestFn.java:425) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all.invokeStatic(chain.clj:186) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$process_all.invoke(chain.clj:182) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$enter_all.invokeStatic(chain.clj:235) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$enter_all.invoke(chain.clj:229) ~[graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$execute.invokeStatic(chain.clj:379) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$execute.invoke(chain.clj:352) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$execute.invokeStatic(chain.clj:389) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.interceptor.chain$execute.invoke(chain.clj:352) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.http.impl.servlet_interceptor$interceptor_service_fn$fn__19447.invoke(servlet_interceptor.clj:350) [graphql-qb-0.4.0-standalone.jar:?] at io.pedestal.http.servlet.FnServlet.service(servlet.clj:28) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:838) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:543) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:188) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1228) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:168) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:481) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:166) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1130) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.Server.handle(Server.java:564) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:318) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:251) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:112) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:672) [graphql-qb-0.4.0-standalone.jar:?] at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:590) [graphql-qb-0.4.0-standalone.jar:?] at java.lang.Thread.run(Thread.java:748) [?:1.8.0_181] Caused by: java.lang.IllegalArgumentException: No implementation of method: :transform-result of protocol: #'graphql-qb.schema/ResultTransform found for class: graphql_qb.types.EnumType

agustingp avatar Oct 08 '18 12:10 agustingp

@agustingp there are some inconsistencies between the URIs used at the cube and the URIs used at the codelists:

  • Cube: http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/buoyid/1 codelist: http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/buoy_id/1 (see the _)

  • Cube http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/latitude/54.23393299999999 codelist: http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/latitude/54-233933

  • Cube http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/longitude/-10.1429codelist http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/longitude/10-1429

  • Cube http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/stationid/belmullet-wave-buoy-berth-b codelist http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/station_id/belmullet-wave-buoy-berth-b (stationid -> station_id)

  • Cube http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/time/2010-01-01T13:30:00Z codelist http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/time/2010-01-01t13-30-00z

zeginis avatar Oct 08 '18 13:10 zeginis

@agustingp - I pushed a fix for that issue earlier today, can you try the latest version on master to see if that works for you?

lkitching avatar Oct 08 '18 13:10 lkitching

@zeginis These missing "_" were just an attempt to see if that was the error (In the documentation there is this example: http://example.gr/def/concept/stationid/{station_id}) @lkitching I run the last update of the API and it works now as expected. Thanks a million

agustingp avatar Oct 08 '18 15:10 agustingp

@agustingp if there is no matching between the cube and the codelist the API will work, but when quering the observations you will get the URI of the values instead of the enum.

e.g. at the data you have at the SPARQL endpoint, the time value URIs do not exist at the codelist

{cubiql{dataset_iwavebnetwork_spectral{
  observations{
    page{
      observation{        
        station_id
        time        
 }    }  }}}}
 "observation": [
         { "station_id": "BELMULLET_WAVE_BUOY_BERTH_B",
            "time": "http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/time/2010-01-01T12:06:00Z"
              },
...

zeginis avatar Oct 09 '18 08:10 zeginis

@zeginis regarding your last comment I realized that what you say is happening, but the values are matching. For instance, Cube <http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/station_id/howth-harbour> . Codelist <http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/station_id/howth-harbour> rdfs:label "Howth Harbour" .

Querying the API:

{ "data": { "cubiql": { "dataset_irishnationaltidegaugenetwork": { "observations": { "page": { "observation": [ { "uri": "http://www.opengovintelligence.eu/statistics/marine-institute/data/irishnationaltidegaugenetwork/-6.0683/53.3915/0/2010-01-01T00:00:00Z/howth-harbour/10/qc_flag", "altitude": "A_0", "station_id": "HOWTH_HARBOUR", "water_level_lat": "", "water_level_od_malin": "", "datasourceid": "A_10" },

agustingp avatar Oct 09 '18 09:10 agustingp

@agustingp the problem occurs only when there is not matching. e.g. at the time dimension. The station_id is ok.

zeginis avatar Oct 09 '18 10:10 zeginis

@zeginis Oh I got it. Thanks!

agustingp avatar Oct 09 '18 10:10 agustingp

@zeginis I modified our script for creating the codelists based on the input file to only slugize the values of the dimensions that have "slugize" as "value_transformation" value. Now time is being retrieved (not the URI) but I still see that the values are being modified:

"observation": [ { "altitude": "A_0", "time": "A_2010_01_01T00_00_00Z", "station_id": "HOWTH_HARBOUR" },

whereas in the Cube definition the values are defined as:

<http://www.opengovintelligence.eu/statistics/marine-institute/def/concept/time/2010-01-01T05:42:00Z> .

The same with Latitude and Longitude dimensions

agustingp avatar Oct 09 '18 10:10 agustingp

@lkitching any idea if this can be fixed somehow?

label: 2010-01-01T05:42:00Z enum: A_2010_01_01T00_00_00Z

zeginis avatar Oct 09 '18 12:10 zeginis

@zeginis @agustingp - At the moment, dimensions with an associated codelist are mapped to a GraphQL enum type. GraphQL enum values must begin with a letter or _ (see the definition in the specification). At the moment, we prefix A_ to enum values that start with an invalid starting character to make the name valid, we could change this to just use an _ alone.

Are you using the codelist values to filter the results? Currently we create an enum type for all dimensions with a codelist but we could change this to look at the rdfs:range first and only generate enum types for certain types. This would allow you to set the rdfs:range to a type which is mapped to a string instead.

lkitching avatar Oct 09 '18 15:10 lkitching

@lkitching what is there the reason for disallowing numbers at the beginning? Is it possible to have a workaround? There are a lot of cases where the dimension value will start with a number (including the ones mentioned by @agustingp):

<http://data.cso.ie/census-2011/classification/size-of-family/6_or_more> <http://www.w3.org/2000/01/rdf-schema#label> "6 or more" .

<http://data.cso.ie/census-2011/classification/number-of-motor-cars/3> <http://www.w3.org/2000/01/rdf-schema#label> "3" .

arekstasiewicz avatar Oct 09 '18 15:10 arekstasiewicz

@arekstasiewicz - This is a restriction GraphQL puts on enum values that they must begin with either a letter or underscore. If you query the dimensions for the dataset you can retrieve the label for each enum value and perform the mapping yourself. We could change the way enum types are output in the schema so you can select the mapped value along with the associated label, this would mean your queries for those dimensions would need to change from

observation {
   uri
   enum_dimension
}

to

observation {
  uri
  enum_dimension {
    value
    schema_label
  }
}

this approach might be a little confusing since it would ignore the lang_preference set for the query.

lkitching avatar Oct 10 '18 09:10 lkitching