How do i add and load data in multiple classes correctly?

Each class works by itself but not when I try to add multiple classes.
Any suggestions?

const hasCityContentSchema = () => {
console.log(’# checking CityContent schema’)
// set database to use to MyDemo1
WOQL.db(‘MyDemo1’)
// check if a class called ‘scm:Object’ exists
// and is a sub of class ‘system:Document’
WOQL.query(Q
.quad(‘v:Class’, ‘type’, ‘owl:Class’, ‘schema’)
.sub(‘system:Document’, ‘v:Class’)
.eq(‘v:Class’, ‘scm:CityContent’)
)
.then(response => {
if (response.bindings.length === 0) {
// add the schema for class ‘scm:City_Content’
console.log(’# creating City Content schema’)
WOQL.query(Q
.doctype(“CityContent”).label(“City_Content”)
.description(‘An Object of type City Content’)
.property(“id”, “xsd:integer”).label(“City Content Id”).cardinality(1)
.property(“content_id”, “xsd:integer”).label(“Content Id”).cardinality(1)
.property(“city_id”, “xsd:integer”).label(“City Id”).cardinality(1)
.property(“name”, “xsd:string”).label(“City Name”)
.and(
WOQL.query(Q
.doctype(“Person_Content”).label(“Person Content”)
.description(‘An Object of type Person Content’)
.property(“id”, “xsd:integer”).label(“Person Content Id”).cardinality(1)
.property(“content_id”, “xsd:integer”).label(“Content Id”).cardinality(1)
.property(“person_id”, “xsd:integer”).label(“Person Id”).cardinality(1)
.property(“first_name”, “xsd:string”).label(“First Name”)
.property(“last_name”, “xsd:string”).label(“Last Name”)
.property(“age”, “xsd:integer”).label(“Person Age”).cardinality(1)
))
).then(response => {
}).catch(error => console.log(‘add City Content Data error’, error))
} else {
console.log(’# Database CityContent schema already created’)
done()
}
})
.catch(error => console.log(‘CityContent error’, error))
}

const addPersonContentData = () => {
console.log(’# add personContent1 data 0’)
WOQL.query(Q
.add_triple(‘doc:personContent1’, ‘type’, ‘scm:PersonContent’)
.add_triple(‘doc:personContent1’, ‘id’, Q.literal(1, ‘xsd:integer’))
.add_triple(‘doc:personContent1’, ‘content_id’, Q.literal(2, ‘xsd:integer’))
.add_triple(‘doc:personContent1’, ‘person_id’, Q.literal(2, ‘xsd:integer’))
.add_triple(‘doc:personContent1’, ‘first_name’, Q.literal(‘Bob’, ‘xsd:string’))
.add_triple(‘doc:personContent1’, ‘last_name’, Q.literal(‘Kid’, ‘xsd:string’))
.add_triple(‘doc:personContent1’, ‘age’, Q.literal(21, ‘xsd:integer’))
.add_triple(‘doc:personContent1’, ‘city_id’, Q.literal(1, ‘xsd:integer’))
.comment(‘Add an PersonContent data 0’)
).then(() => {
console.log(’# add personContent2 data 1’)
WOQL.query(Q
.add_triple(‘doc:personContent2’, ‘type’, ‘scm:PersonContent’)
.add_triple(‘doc:personContent2’, ‘id’, Q.literal(2, ‘xsd:integer’))
.add_triple(‘doc:personContent2’, ‘content_id’, Q.literal(4, ‘xsd:integer’))
.add_triple(‘doc:personContent2’, ‘person_id’, Q.literal(4, ‘xsd:integer’))
.add_triple(‘doc:personContent2’, ‘first_name’, Q.literal(‘Kim’, ‘xsd:string’))
.add_triple(‘doc:personContent2’, ‘last_name’, Q.literal(‘Hugs’, ‘xsd:string’))
.add_triple(‘doc:personContent2’, ‘age’, Q.literal(21, ‘xsd:integer’))
.add_triple(‘doc:personContent2’, ‘city_id’, Q.literal(3, ‘xsd:integer’))
.comment(‘Add an PersonContent data 1’)
).then(() => {
}).catch(error => console.log(‘PersonContent Data 1 error’, error))
}).catch(error => console.log(‘PersonContent Data 0 error’, error))
}

The property ids have to be globally unique - so the properties “id” and “content_id” of CityContent and Person_Content will clash.

To fix you should either

  • create a superclass and give it the shared properties and make your doctypes subtypes of this class and they will inherit the common properties
WOQL.doctype("Base").property("id", "integer").property("content_id", "integer")
...
WOQL.doctype("CityContent").parent("Base")
...

or 2) make the property ids distinct:

WOQL.doctype("CityContent").property("city_id", "integer") 

or

Kevin, Thanks. I am attempting to put together a prototype with TerminusDB to see if the merging/revisioning capability is adequate for my needs. I appreciated your prompt support. I will try the superclass suggestion initially.
orioncri

I am still having issues loading my second City class with data (addCityData). Any suggestions would be helpful. Below are my changes and the error.

The error:

Checking Database

has Database

Checking Object Schema

Checking City Schema

add city1 data 0

add object1 data 0

City Data 0 error { Error: API Error Code: 405 url: https://127.0.0.1:6363/api/woql/admin/MyDemo1/local/branch/main
at DispatchRequest.axiosInstance.post.then.catch.err (/home/rrivas/JAVA-workspace/TodoApp/node_modules/@terminusdb/terminusdb-client/lib/dispatchRequest.js:132:31)
at process._tickCallback (internal/process/next_tick.js:68:7)
data:
[ { ‘@type’: ‘vio:InstanceCardinalityRestrictionViolation’,
‘vio:cardinality’: [Object],
‘vio:message’: [Object],
‘vio:predicate’: [Object],
‘vio:restriction’: [Object],
‘vio:subject’: [Object] } ] }

add object2 data 1

add object3 data 2

add object4 data 3

add object5 data 4

add object6 data 5

add object7 data 6

add object8 data 7

add object9 data 8

Done

const hasSchema = () => {
console.log(’# Checking Object Schema’)
// set database to use to MyDemo1
WOQL.db(‘MyDemo1’)
// check if a class called ‘scm:Object’ exists
// and is a sub of class ‘system:Document’
WOQL.query(Q
.quad(‘v:Class’, ‘type’, ‘owl:Class’, ‘schema’)
.sub(‘system:Document’, ‘v:Class’)
.eq(‘v:Class’, ‘scm:Object’)
)
.then(response => {
if (response.bindings.length === 0) {
console.log(’# Creating Object Schema’)
// add the Schema for class ‘scm:Object’
WOQL.query(Q
.doctype(‘Object’).label(‘Object’)
.description(‘An Object is either a City, Person or Null’)
.property(‘id’, ‘xsd:integer’).label(“Id”).cardinality(1)
.property(‘completed’, ‘xsd:boolean’).label(“Completed”).cardinality(1)
).then(response => {
console.log(’# Created Object Schema’)
// add the Schema for class ‘scm:Object’
console.log(’# Creating City Schema’)
WOQL.query(Q
.doctype(“City”).label(“City”).parent(‘Object’)
.description(‘An Object of type City’)
.property(“object_id”, “xsd:integer”).label(“Object Id”).cardinality(1)
).then(response => {
}).catch(error => console.log(‘add City Data error’, error))
}).catch(error => console.log(‘add Object Data error’, error))
} else {
console.log(’# Object Schema already Created’)
done()
}
})
.catch(error => console.log(‘error’, error))
}

const addCityData = () => {
console.log(’# Checking City Schema’)
// set database to use to MyDemo1
WOQL.db(‘MyDemo1’)
// check if a class called ‘scm:Object’ exists
// and is a sub of class ‘system:Document’
WOQL.query(Q
.quad(‘v:Class’, ‘type’, ‘owl:Class’, ‘schema’)
.sub(‘scm:Object’, ‘v:Class’)
.eq(‘v:Class’, ‘scm:City’)
)
.then(response => {
console.log(’# add city1 data 0’)

	WOQL.query(Q
			.add_triple('doc:city1', 'type', 'scm:City')
			.add_triple('doc:city1', 'id', Q.literal(1, 'xsd:integer'))
			.add_triple('doc:city1', 'object_id', Q.literal(1, 'xsd:integer'))
			.comment('Add an City data 0')
	).then(() => {
		console.log('# add city2 data 1')
		WOQL.query(Q
				.add_triple('doc:city2', 'type', 'scm:City')
				.add_triple('doc:city2', 'id', Q.literal(2, 'xsd:integer'))
				.add_triple('doc:city2', 'object_id', Q.literal(3, 'xsd:integer'))
				.comment('Add an City data 1')
		).then(() => {
			console.log('# add city3 data 2')
			WOQL.query(Q
					.add_triple('doc:city3', 'type', 'scm:City')
					.add_triple('doc:city3', 'id', Q.literal(3, 'xsd:integer'))
					.add_triple('doc:city3', 'object_id', Q.literal(5, 'xsd:integer'))
					.comment('Add an City data 2')
			).then(() => {
			}).catch(error => console.log('City Data 2 error', error))
		}).catch(error => console.log('City Data 1 error', error))
	}).catch(error => console.log('City Data 0 error', error))
}).catch(error => console.log('City Schema error', error))

}

aha, I think I get it.
You can add the two cities in the same woql - you don’t need multiple queries:

WOQL.query(Q
			.add_triple('doc:city1', 'type', 'scm:City')
			.add_triple('doc:city1', 'id', Q.literal(1, 'xsd:integer'))
			.add_triple('doc:city1', 'object_id', Q.literal(1, 'xsd:integer'))
			.add_triple('doc:city2', 'type', 'scm:City')
            .add_triple('doc:city2', 'id', Q.literal(2, 'xsd:integer'))
		    .add_triple('doc:city2', 'object_id', Q.literal(3, 'xsd:integer'))
)

should work fine

1 Like

Thanks. Should I be able to add different classsc/tables as well in the same query. I would add an add_triple to the ‘scm:Object’ table as well in the same query?

Yes, woql queries are completely compositional - you can always do and(Q1, Q2…) and all will be executed as a single transaction.