def execute_commit(qlist): global client, polity_query_name, polity_query global total_assertions, total_inserts, total_deletes, total_commit_failures msg = f"Committing data for {polity_query_name}" try: q = WOQLQuery().woql_and(*qlist) execute_start_time = time.time() result = q.execute(client, commit_msg=msg) # Makes no difference to timing: client.squash(msg) # per Kevin: flatten the 'journal' execute_elapsed_s = "%.2fs" % (time.time() - execute_start_time) total_assertions += 1 if type(result) is dict: inserts = result['inserts'] deletes = result['deletes'] total_inserts += inserts total_deletes += deletes print(f"{msg} i:{inserts} d:{deletes} {execute_elapsed_s}") else: # Sometimes we get a <Response> object that is not subscriptable? # result.status_code is the HTTP status code, 200 is successful but we don't have bindings? print(f"{msg} {execute_elapsed_s}") if dump_results: pprint.pprint(result, indent=4) except Exception as exception: # API error or whatever execute_elapsed_s = "%.2fs" % (time.time() - execute_start_time) print( f"Execution ERROR while {msg} after {execute_elapsed_s} -- skipped" ) print(f"{exception.msg}") total_commit_failures += 1
def create_schema(client, commit_msg): """The query which creates the schema Parameters - it uses variables rather than the fluent style as an example ========== client : a WOQLClient() connection """ station_dt = WOQLQuery().doctype( "Station", label="Bike Station", description="A station where bikes are deposited") bicycle_dt = WOQLQuery().doctype("Bicycle", label="Bicycle") journey_dt = (WOQLQuery().doctype("Journey", label="Journey").property( "start_station", "Station", label="Start Station").property( "end_station", "Station", label="End Station").property("duration", "integer", label="Journey Duration").property( "start_time", "dateTime", label="Time Started").property( "end_time", "dateTime", label="Time Ended").property( "journey_bicycle", "Bicycle", label="Bicycle Used")) schema = station_dt + bicycle_dt + journey_dt return schema.execute(client, commit_msg)
def generateMatchClause(code, type, i): """ Bug in python string conversion < 0.0.19 - fixed thereafter """ match = WOQLQuery().woql_and( WOQLQuery().idgen("doc:" + type, [code], "v:ID_" + str(i)), WOQLQuery().cast(code, "xsd:string", "v:Label_" + str(i)) #WOQLQuery().idgen("doc:" + type, [{"@value": code, "@type": "xsd:string"}], "v:ID_"+str(i)), #WOQLQuery().cast({"@value": code, "@type": "xsd:string"}, "xsd:string", "v:Label_"+ str(i)) ) return match
def generateMultiInsertQuery(codes, type): matches = [] inserts = [] index = 0 for code in codes: matches.append(generateMatchClause(code, type, index)) inserts.append(generateInsertClause(code, type, index)) index = index + 1 return WOQLQuery().when(WOQLQuery().woql_and(*matches), WOQLQuery().woql_and(*inserts))
def load_csvs(client, csvlist, wrangl, insert): """Load the CSVs as input Parameters ========== client : a WOQLClient() connection csvs : a dict of all csvs to be input """ for url in csvlist: csv = get_csv_variables(url) inputs = WOQLQuery().woql_and(csv, *wrangl) answer = WOQLQuery().when(inputs, insert) answer.execute(client, f"loading {url} into the graph")
def build_schema(client): spacy_doc = WOQLQuery().doctype("SpaCyDoc", label="SpaCy Document", description="The Document object in SpaCy") token_dt = (WOQLQuery().doctype( "SpaCyToken", label="SpaCy Tokens").property("lemma", "string").property( "pos", "string").property("tag", "string").property( "dep", "string").property("shape", "string").property( "is_alpha", "boolean").property("is_stop", "boolean").property( "head", "SpaCyToken").property("doc", "SpaCyDoc")) schema = spacy_doc + token_dt return schema.execute(client, "Create a schema for SpaCy Tokens")
def create_schema(client): # creating objects doctype movie_obj = WOQLQuery().doctype("Movie", label="Movie Title", description="Movie short description") person_obj = WOQLQuery().doctype("Person", label="Name of the person") genre_obj = WOQLQuery().doctype("Genre", label="Genre of a movie") # adding property movie_obj = (movie_obj .property("Director", "Person", label="Dirctor of the movie") .property("Cast", "Person", label="Cast of the movie") .property("MovieGenre", "Genre", label="Genre of the movie") .property("Year", "xsd:integer", label="Year of release") .property("Runtime", "xsd:integer", label="Runtime", description="Runtime of the movie in mins") .property("Rating", "xsd:decimal", label="Rating of the movie", description="User rating for the movie 0-10") .property("Votes", "xsd:integer", label="Votes", description="Number of votes") ) WOQLQuery().woql_and(movie_obj, genre_obj, person_obj).execute(client, "Building Schema for the movie graph")
def post(self, request, *args, **kwargs): WOQLQuery().insert("stu002", "scm:student") \ .property("scm:name", request.data['name']) \ .execute(client) # Generate response return Response({'message': 'ok'})
def get_csv_variables(url): """Extracting the data from a CSV and binding it to variables Parameters ========== client : a WOQLClient() connection url : string, the URL of the CSV """ csv = WOQLQuery().get( WOQLQuery().woql_as("Start station", "v:Start_Station").woql_as( "End station", "v:End_Station").woql_as("Start date", "v:Start_Time").woql_as( "End date", "v:End_Time").woql_as("Duration", "v:Duration").woql_as( "Start station number", "v:Start_ID").woql_as( "End station number", "v:End_ID").woql_as("Bike number", "v:Bike").woql_as( "Member type", "v:Member_Type")).remote(url) return csv
def get_inserts(): inserts = WOQLQuery().woql_and( WOQLQuery().insert("v:Journey_ID", "Journey", label="v:Journey_Label", description="v:Journey_Description"). property("start_time", "v:Start_Time_Cast"). property("end_time", "v:End_Time_Cast"). property("duration", "v:Duration_Cast"). property("start_station", "v:Start_Station_URL"). property("end_station", "v:End_Station_URL"). property("journey_bicycle", "v:Bike_URL"), WOQLQuery().insert("v:Start_Station_URL", "Station", label="v:Start_Station_Label"), WOQLQuery().insert("v:End_Station_URL", "Station", label="v:End_Station_Label"), WOQLQuery().insert("v:Bike_URL", "Bicycle", label="v:Bike_Label") ) return inserts
def loading_data(client, file_url): read_csv = WOQLQuery().get( WOQLQuery().woql_as("Rank", "v:rank_raw") .woql_as("Title", "v:title_raw") .woql_as("Genre", "v:genre_raw") .woql_as("Description", "v:description_raw") .woql_as("Director", "v:director_raw") .woql_as("Actors", "v:actors_raw") .woql_as("Year", "v:year_raw") .woql_as("Runtime (Minutes)", "v:runtime_raw") .woql_as("Rating", "v:rating_raw") .woql_as("Votes", "v:votes_raw") .woql_as("Revenue (Millions)", "v:rev_raw") .woql_as("Metascore","v:metascore_raw") ).remote(file_url) prepare_genre_obj = WOQLQuery().split("v:genre_raw", ", ", "v:genre_list").member("v:one_genre", "v:genre_list").idgen("doc:Genre", ["v:one_genre"], "v:genre_objid") prepare_actor_obj = WOQLQuery().split("v:actors_raw", ", ", "v:actors_list").member("v:one_actor", "v:actors_list").idgen("doc:Person", ["v:one_actor"], "v:actors_objid") prepare_director_obj = WOQLQuery().split("v:director_raw", ", ", "v:director_list").member("v:one_director", "v:director_list").idgen("doc:Person", ["v:one_director"], "v:director_objid") wangles = ( WOQLQuery().typecast("v:year_raw", "xsd:integer", "v:year_clean") .typecast("v:runtime_raw", "xsd:integer", "v:runtime_clean") .typecast("v:rating_raw", "xsd:decimal", "v:rating_clean") .typecast("v:votes_raw", "xsd:integer", "v:votes_clean") .idgen("doc:Movie",["v:title_raw", "v:director_raw"], "v:movie_id") ) insert = ( WOQLQuery().insert("v:genre_objid", "Genre", label="v:one_genre") .insert("v:actors_objid", "Person", label="v:one_actor") .insert("v:director_objid", "Person", label="v:one_director") .insert("v:movie_id", "Movie", label="v:title_raw", description="v:description_raw") .property("Director", "v:director_objid") .property("Cast", "v:actors_objid") .property("MovieGenre", "v:genre_objid") .property("Year", "v:year_clean") .property("Runtime", "v:runtime_clean") .property("Rating", "v:rating_clean") .property("Votes", "v:votes_clean") ) data_prep = WOQLQuery().woql_and(read_csv, prepare_genre_obj, prepare_actor_obj, prepare_director_obj, wangles) return WOQLQuery().woql_and(data_prep, insert).execute(client, "Loading data for the movie graph")
def get_wrangles(): wrangles = [ WOQLQuery().idgen("doc:Journey", [ "v:Start_ID", "v:Start_Time", "v:Bike"], "v:Journey_ID"), WOQLQuery().idgen("doc:Station", [ "v:Start_ID"], "v:Start_Station_URL"), WOQLQuery().cast("v:Duration", "xsd:integer", "v:Duration_Cast"), WOQLQuery().cast("v:Bike", "xsd:string", "v:Bike_Label"), WOQLQuery().cast("v:Start_Time", "xsd:dateTime", "v:Start_Time_Cast"), WOQLQuery().cast("v:End_Time", "xsd:dateTime", "v:End_Time_Cast"), WOQLQuery().cast("v:Start_Station", "xsd:string", "v:Start_Station_Label"), WOQLQuery().cast("v:End_Station", "xsd:string", "v:End_Station_Label"), WOQLQuery().idgen("doc:Station", ["v:End_ID"], "v:End_Station_URL"), WOQLQuery().idgen("doc:Bicycle", ["v:Bike_Label"], "v:Bike_URL"), WOQLQuery().concat("Journey from v:Start_ID to v:End_ID at v:Start_Time", "v:Journey_Label"), WOQLQuery().concat("Bike v:Bike from v:Start_Station to v:End_Station at v:Start_Time until v:End_Time", "v:Journey_Description") ] return wrangles
def create_seshat_schema(client): """The query which creates the schema Parameters - it uses variables rather than the fluent style as an example ========== client : a WOQLClient() connection """ # presummably this goes into 'scm:' by default # what do I do if I wanted to name the schema to publish it (like bike_scm)? # presummably I would have to then dump it in rdf format and make it available on the web for parsing by other 3store apps right? # what do I use to load an external schema? # This controls 'debugging mode' True to incrementally execute, False to append and execute once execute_incrementally = False # if False, flat defined in 7s; if True, 577s def process_q(q, message=None): if execute_incrementally: if message is not None: print(message) try: q.execute(client, commit_msg=message) except Exception as exception: # API error or whatever print(f"Execution ERROR for: {message} -- skipped") print(f"{exception.msg}") return q # kevin.js: initial un-numbered q q = WOQLQuery().doctype( "Organization", label="Organization", description= "A human organization of any type - has the capacity to act as a unit, in some sense" ).abstract() all_q = process_q(q, "Organization") for class_defn in class_defns: if len(class_defn) == 4: name, label, description, parents = class_defn else: name, label, description = class_defn parents = [] # name = normaliseID(name,'id') q = WOQLQuery().doctype(name, label=label, description=description) for parent in parents: # parent = normaliseID(parent,'id') q.parent(parent) all_q = all_q + process_q(q, name) # kevin.js: q2 q = WOQLQuery().doctype( "Topic", label="Topic Class", description="A class that represents a topic").abstract() all_q = all_q + process_q(q, "Topic") for topic in topics: if len(topic) == 4: name, label, description, parents = topic else: name, label, description = topic parents = [] # name = normaliseID(name,'id') q = WOQLQuery().doctype(name, label=label, description=description) for parent in parents: # parent = normaliseID(parent,'id') q.parent(parent) all_q = all_q + process_q(q, name) q = WOQLQuery().doctype("CitedWork", label="Cited Work").property( "remote_url", "xsd:anyURI") all_q = all_q + process_q(q, 'CitedWork') # This call defines the boxed datatypes we use, e.g., scm:IntegerRange whose 'type' is xdd:IntegerRange # kevin.js: q9 if False: q = (WOQLQuery().add_class("scm:Box").label("Box Class").description( "A class that represents a boxed datatype").abstract()) all_q = all_q + process_q(q, 'scm:Box') for bbt in boxed_basic_types: datatype, label, description = bbt raw_datatype = ensure_raw_type( datatype) # how we are actually storing it Datatype = normaliseID( datatype, 'type' ) # get the scm: prefixed, upper-cased name, e.g., scm:GYear from xsd:gYear no_prefix_Datatype = Datatype.split(":")[1] type_info[no_prefix_Datatype] = (Datatype, datatype) if verbose: print( f"box type property: {Datatype} domain: {Datatype} type: {datatype} as {raw_datatype}" ) qt = WOQLQuery().add_class(Datatype).label(label) if False: # no parent, e.g., scm:Box, needs to be added to qt so far (except it bundles all our types together) qt.parent('scm:Box') # scm:Integer is a class with a property scm:Integer that permits an xsd:integer # when when we mixin scm:Integer into a <prop>_Value class, and it has type xsd:integer qp = (WOQLQuery().add_property(Datatype, raw_datatype).domain( Datatype).label(label).description(description)) q = WOQLQuery().woql_and(qt, qp) all_q = all_q + process_q(q, Datatype) # kevin.js: q5+q6 # Is this class needed for generate_choice_list()? # JSB probably not. it is like Box which just serves to organize the different types # q = WOQLQuery().doctype("Enumerated",label="Enumerated Type",description="A type that consists of a fixed set of choices") # all_q = all_q + process_q(q,"Enumerated") for etype in enumerations: Name, label, description, choices = etype Name = Name[0].upper() + Name[1:] # ensure leading capitlized scm_Name = normaliseID(Name, 'id') # e.g., scm:EpistemicState if False: # DEBUG since fixed_generate_choice_list() uses prefix _:, which causes upset # choices = normaliseID(choices,'id') for choice in choices: choice[0] = normaliseID(choice[0], 'id') # q = WOQLQuery().generate_choice_list(name,clslabel=label,clsdesc=description,choices=choices) qus = fixed_generate_choice_list(cls=scm_name, clslabel=label, clsdesc=description, choices=choices) qsc = fixed_generate_choice_list(cls=scm_scoped_name, clslabel=label, clsdesc=description, choices=choices) q = WOQLQuery().woql_and(qus, qsc) else: # HACK define the class but not its structure # treat it like a Box type with a string raw_type = ensure_raw_type(scm_Name) if raw_type != 'xsd:string': print(f"Incorrect ensure_raw_type() entry for {scm_Name}") continue # class scm:EpistemicState with property EpistemicState of type xsd:string # class scm:Confidence with property scm:Confidence of type xsd:string # << this is used in property_Value confidence type_info[Name] = (scm_Name, scm_Name) if verbose: print(f"enumeration property: {scm_Name} domain: {scm_Name}") qt = WOQLQuery().add_class(scm_Name).label(label) qp = (WOQLQuery().add_property(scm_Name, raw_type).domain( scm_Name).label(label).description(description)) q = WOQLQuery().woql_and(qt, qp) all_q = all_q + process_q(q, f"{scm_Name}") # define these after types and enumerations so we can refer to them # kevin.js: q7 q = (WOQLQuery().add_class("Note").label("A Note on a value").description( "Editorial note on the value").property( "citation", "scm:CitedWork").label( "Citation").description("A link to a cited work").property( "quotation", "xsd:string").label("Quotation").description( "A quotation from a work")) all_q = all_q + process_q(q, 'Note') q = ( WOQLQuery().add_class("ScopedValue").abstract() # These were xdd:integerRange # Don't we want these to be xsd:gYear and not a range? # Peter says we should always permit 'unknown' and 'suspected unknown' as a value # Thus we should add the following. If it is NOT asserted, then lookup its usual typed value # Otherwise the string is 'unknown' (high confidence) or 'suspected unknown' (low confidence) (another enum) and remove it from EpistemicState # .property("unknown", 'xsd:string').label("Unknown").description("Whether the value is unknown") .property("start", raw_gYear_type).label("From").description( "The start of a time range").property("end", raw_gYear_type). label("To").description("The end of a time range").property( "confidence", "scm:Confidence").label("Confidence").description( "Qualifiers of the confidence of a variable value").property( "notes", "scm:Note").label("Notes").description( "Editorial notes on values")) all_q = all_q + process_q(q, 'ScopedValue') # kevin.js: q11 for p in unscoped_properties: if len(p) == 5: npid, nptype, label, description, domain = p else: npid, nptype, label, description = p domain = "scm:PoliticalAuthority" # TODO no prefix nptype? variable_info[label] = (npid, False, nptype ) # do this before adding scm: to npid! npid = normaliseID(npid, "id") # add scm: if missing a prefix raw_nptype = ensure_raw_type(nptype) q = WOQLQuery().add_property( npid, raw_nptype).label(label).description(description).domain(domain) all_q = all_q + process_q(q, npid) # kevin.js: q15 for p in scoped_properties: if len(p) == 6: npid, nptype, parents, label, description, domain = p else: npid, nptype, parents, label, description = p domain = "scm:PoliticalAuthority" parents = normaliseID(parents, "id") parents.append( "scm:ScopedValue" ) # these seshat polity properties always inherit from ScopedValue -- that is where datatypes and values are stored nptype = normaliseID(nptype, "type") # convert to our boxed types always # No need to lookup 'raw' type -- that was done up when we defined our boxed types no_prefix_nptype = nptype.split(":")[1] variable_info[label] = (npid, True, no_prefix_nptype ) # before we add scm: to npid npid = normaliseID(npid, "id") parents.append(nptype) newclass = npid + "_Value" if verbose: print( f"property: {npid} domain: {domain} type: {newclass} parents: {parents}" ) q = WOQLQuery().add_class(newclass).label(label).description( description) for parent in parents: q.parent(parent) all_q = all_q + process_q(q, newclass) q = WOQLQuery().add_property( npid, nptype).label(label).description(description).domain(domain) all_q = all_q + process_q(q, npid) if not execute_incrementally: execute_incrementally = True # force execution process_q(all_q, "Defining the Seshat Schema") return True
else: client.db(db_id) """ # station_dt = WOQLQuery().doctype("doc_car", # label="doc_car", # description="A station where bikes are deposited") # station_dt.execute(client, "creating schema") # carInstance = WOQLQuery().insert(insert_id="OBJ123", insert_type="doc_car") # carInstance.label("Porche 911") # carInstance.property("car_make", "Porche") # carInstance.property("car_model", "911") # carInstance.execute(client) WOQLQuery().doctype("scm:student").property("scm:name", "xsd:string").execute(client, "student schema created.") WOQLQuery().insert("stu001", "scm:student").property("scm:name", "Alice").execute(client, "Adding Alice.") WOQLQuery().insert("stu002", "scm:student").property("scm:name", "Bob").execute(client, "Adding Bob.") client.query(WOQLQuery().star()) """ station_dt = WOQLQuery().doctype("station", label="Bike Station", description="A station where bikes are deposited") bicycle_dt = WOQLQuery().doctype("bike", label="Bicycle") journey_dt = ( WOQLQuery().doctype("journey", label="Journey"). property("start_station", "Station", label="Start Station"). property("end_station", "Station", label="End Station"). property("duration", "integer", label="Journey Duration"). property("start_time", "dateTime", label="Time Started"). property("end_time", "dateTime", label="Time Ended").
#!/usr/bin/python3 from terminusdb_client import WOQLClient from terminusdb_client import WOQLQuery server_url = "https://127.0.0.1:6363" client = WOQLClient(server_url) client.connect(user="******", account="admin", key="root", db="bike") client.delete_database("bike") client.create_database("bike","admin",label="Bikes", description="description") query = WOQLQuery().get( WOQLQuery().woql_as("Start station","v:Start_Station") .woql_as("End station", "v:End_Station") .woql_as("Start date", "v:Start_Time") .woql_as("End date", "v:End_Time") .woql_as("Duration", "v:Duration") .woql_as("Start station number", "v:Start_ID") .woql_as("End station number", "v:End_ID") .woql_as("Bike number", "v:Bike") .woql_as("Member type", "v:Member_Type") ).post("bike_csv") result = client.query(query, "This is a commit string", {'bike_csv' : '/home/gavin/tmp/bike_tutorial.csv'})
def generateInsertClause(code, type, i): insert = WOQLQuery().woql_and(WOQLQuery().insert( "v:ID_" + str(i), type).label("v:Label_" + str(i))) return insert
def assert_seshat_row(Polity, Variable, Value_From, Value_To, Date_From, Date_To, Fact_Type, Value_Note): global client, flushed_values, polity_query_name, polity_query empty_value = '' # Could be None def unique_var(prefix): uid = increment_unique_id() return f"{prefix}_{uid}" if polity_query_name != Polity: if polity_query is not None: execute_commit(polity_query) # fallthrough polity_query_name = Polity polity_query = [ ] # add individual queries to the list for a final woql_and in execute_commit() try: property_name, scoped, property_type = variable_info[Variable] except KeyError: print(f"WARNING: Unknown property {Variable} - skipping") return None if scoped: property_Value = property_name + '_Value' doc_property_Value = 'doc:' + property_Value scm_property_Value = 'scm:' + property_Value try: property_value_name, raw_type = type_info[property_type] except KeyError: print( f"WARNING: Unknown type {property_type} for {Variable} - skipping" ) return None else: raw_type = property_type real_raw_type = ensure_raw_type(raw_type) lower_Polity = Polity.lower( ) # Make canonical;this was the previous encoding idea for ids where = f"{Polity}|{Variable}" # normally (like on the wiki or on another web interface) we would present all the Scoped values # for a variable and then reassert them enmass, deleting the prior versions # However, with a csv we don't know the order of the lines for all the multiple values # so we maintain a dict of what variables we've started to assert and if # this is a new variable we delete all the extant triples # this assumes, of course, that the csv contains, eventually, all the values for the property # and not just additions try: flushed_values[Polity] new_polity = False except KeyError: flushed_values[Polity] = [ ] # what variables have been flushed this session new_polity = True if new_polity: # TODO how do you bind all the instances of an scm:Polity to a variable? qp = WOQLQuery().woql_or( WOQLQuery().triple( 'v:Polity_ID', 'original_PolID', Polity ), # look up original if it exists under the lower_Polity name # Doesn't exist so create a Polity instance WOQLQuery().woql_and( WOQLQuery().idgen( lower_Polity, [], 'v:Polity_ID' ), # create an atom (why can't we use a raw string?) ( WOQLQuery().insert( 'v:Polity_ID', 'scm:Polity', label=Polity). # create in instance of scm:Polity property('original_PolID', Polity) ))) # record the original 'spelling', e.g. AfHepht vs. afhepht polity_query.append(qp) # collect up all property queries for each Polity and when it changes, execute the collection once if Variable not in flushed_values[Polity]: # do this once, if at all for each property_name flushed_values[Polity].append(Variable) # flushed done old_value_var = unique_var('v:Old_Values') # It is ok that this fails since it might be a new property # or a new class instance without any property at all qf = WOQLQuery() if scoped: qf.opt(WOQLQuery().woql_and( WOQLQuery().triple('v:Polity_ID', property_name, old_value_var), # TODO the Old_Values scoped value instances could have notes # and those instance need to be deleted as well # BUT NOT the CitedWork which might be shared # Do it before deleting the value object WOQLQuery().delete_triple('v:Polity_ID', property_name, old_value_var), WOQLQuery().delete_object(old_value_var))) else: # if unscoped just drop triples directly # but if the values happen to be instance themselves, .e.g, Politys, don't delete them qf.opt(WOQLQuery().woql_and( WOQLQuery().triple('v:Polity_ID', property_name, old_value_var), WOQLQuery().delete_triple('v:Polity_ID', property_name, old_value_var))) polity_query.append(qf) qv = WOQLQuery() # updated/continued by side effect value = Value_From if 'Range' in raw_type: if Value_To != empty_value: value = Value_From + ':' + Value_To # don't use - as separator value = precast_values(value, raw_type, where) dates = '' confidence = '' if scoped: # generate an instance of a scoped data value type pv_var = unique_var('v:propertyValue_ID') unique_id( qv, doc_property_Value, [lower_Polity], pv_var ) # will this generate a new id each time and ensure unique id qv.insert( pv_var, scm_property_Value) # create an instance of the Value boxed class qv.add_triple('v:Polity_ID', property_name, pv_var) # assert the scoped property value # get type, if enumerated check that the given value is (lower) the allowed value # else cast to type # do dates handle CE and BCE and AD and BC? inferred = False if 'inferred' in value: # test scoped here; if not scoped we have a problem inferred = True value = value.split(' ')[1] val_var = unique_var('v:Value') qv.cast(value, real_raw_type, val_var) qv.add_triple( pv_var, property_value_name, val_var ) # store the cast value on the proper property name on the _value instance # NOTE: hard coded information about types under ScopedValue # if those types changes in the schema, this code must change as well if Date_From != empty_value: # Does gYear handle 450CE? NO # under ScopedValue why not dates as integerRange rather than start and end? Date_From = precast_values(Date_From, gYear_type, f"{where}_DateFrom") df_var = unique_var('v:Date_From') qv.cast( Date_From, raw_gYear_type, df_var ) # cast'ing to xsd:gYear fails to return anything and does not complain qv.add_triple(pv_var, 'start', df_var) dates = dates + f":{Date_From}" if Date_To != empty_value: Date_To = precast_values(Date_To, gYear_type, f"{where}_DateTo") dt_var = unique_var('v:Date_To') qv.cast( Date_To, raw_gYear_type, dt_var ) # cast'ing to xsd:gYear fails to return anything and does not complain qv.add_triple(pv_var, 'end', dt_var) dates = f"[{Date_From},{Date_To}]" # TODO require scoped to deal with disputed else badly formed csv if scoped and Value_Note == 'disputed': # eventually we need to convert 'disputed' into the enumerated value in the class # name an instance of ScopedConfidence and assert property 'String' cd_var = unique_var('v:SVcd') unique_id(qv, 'doc:Confidence', [Polity, property_name], cd_var) qv.insert(cd_var, Confidence_type) # make a Confidence instance cdv_var = unique_var('v:SVcdv') # Does cast deal w/ enums? qv.cast( Value_Note, raw_Confidence_type, cdv_var ) # eventually not 'disputed' but a variable bound to the right enum instance with disputed as 'label' qv.add_triple(cd_var, Confidence_type, cdv_var) # The property has the name as the class! # add the Confidence instance to the ScopedValue instance NOTE the cardinality of confidence must be > 1 qv.add_triple(pv_var, 'confidence', cd_var) confidence = confidence + f" {Value_Note}" # Note we can have multiple 'confidence' assertions such as 'disputed' and 'inferred'? for the same 'value'? Happens in the db, e.g., # NGA|CnLrJin|Warfare variables|Military Technologies|Incendiaries|inferred present||||simple|disputed|| # NGA|CnLrJin|Warfare variables|Military Technologies|Incendiaries|present||||simple|disputed|| # TODO require scoped to deal with inferred else badly formed csv if scoped and inferred: ci_var = unique_var('v:SVci') unique_id(qv, 'doc:Confidence', [Polity, property_name], ci_var) qv.insert(ci_var, Confidence_type) # make a Confidence instance civ_var = unique_var('v:SVciv') # Does cast deal w/ enums? qv.cast( 'inferred', raw_Confidence_type, civ_var ) # eventually not 'inferred' but a variable bound to the right enum instance with disputed as 'label' qv.add_triple(ci_var, Confidence_type, civ_var) # The property has the name as the class! # add the Confidence instance to the ScopedValue instance NOTE the cardinality of confidence must be > 1 qv.add_triple(pv_var, 'confidence', ci_var) confidence = confidence + " inferred" # TODO any Date_Note save as a Note instance (v:Note) and assert qv.property('notes','v:Note') else: # unscoped qv.cast(value, real_raw_type, val_var) qv.add_triple('v:Polity_ID', property_name, val_var) polity_query.append(qv) if verbose_mode: print(f"Added {value}{dates}{confidence} for {Variable} on {Polity}") return
def create_schema(client): """The query which creates the schema Parameters - it uses variables rather than the fluent style as an example ========== client : a WOQLClient() connection """ base = WOQLQuery().doctype("EphemeralEntity").label( "Ephemeral Entity").description("An entity that has a lifespan") base.property("lifespan_start", "dateTime").label("Existed From") base.property("lifespan_end", "dateTime").label("Existed To") country = WOQLQuery().add_class("Country").label("Country").description( "A nation state").parent("EphemeralEntity") country.property("iso_code", "string").label("ISO Code") country.property("fip_code", "string").label("FIP Code") airline = WOQLQuery().add_class("Airline").label("Airline").description( "An operator of airplane flights").parent("EphemeralEntity") airline.property("registered_in", "Country").label("Registered In"), airport = WOQLQuery().add_class("Airport").label("Airport").description( "An airport where flights terminate").parent("EphemeralEntity") airport.property("situated_in", "Country").label("Situated In"), flight = WOQLQuery().add_class("Flight").label("Flight").description( "A flight between airports").parent("EphemeralEntity") flight.property("departs", "Airport").label("Departs") flight.property("arrives", "Airport").label("Arrives") flight.property("operated_by", "Airline").label("Operated By") schema = WOQLQuery().when(True).woql_and(base, country, airline, airport, flight) return schema.execute(client)
import terminusdb_client as woql from terminusdb_client import WOQLQuery import sys db_id = "student" client = woql.WOQLClient(server_url = "https://127.0.0.1:6363", insecure=True) client.connect(key="root", account="admin", user="******") existing = client.get_database(db_id, "admin") if existing is not None: client.delete_database(db_id) client.create_database(db_id, accountid="admin", label = "Student", description = "Create a graph with student data") WOQLQuery().doctype("scm:student").property("scm:name", "xsd:string").execute(client, "student schema created.") WOQLQuery().insert("stu002", "scm:student") \ .property("scm:name", "Bob") \ .execute(client, "Adding Bob.")
from terminusdb_client import WOQLQuery as WOQL # Connect to the server server_url = "https://127.0.0.1:6363" db = "dbpedia_1" user = "******" account = "admin" key = "root" client = WOQLClient(server_url) client.connect(user=user, account=account, key=key, db=db) # Example of a single hop query = WOQL().limit( 1, WOQL.woql_and( WOQL().path("doc:Whitesnake", "scm:bandMember", "v:Member", "v:Path"), )) result = client.query(query) print(f"Band member: {result['bindings'][0]['Member']}") query = WOQL().limit( 1, WOQL.woql_and( WOQL().path("doc:Whitesnake", "scm:bandMember,scm:birthPlace", "v:Place", "v:Path"), )) result = client.query(query) print(result['bindings'][0]) query = WOQL().limit( 3, WOQL().select("v:P", "v:Result").woql_and(
def insert_triple(): subj = random_string_number() pred = random_string_number() value = random_string_number() WOQLQuery().using(f"admin/{db}").add_triple(subj, pred, value).execute(client)