def test_load_by_oclass(self): """Test loading by oclass.""" c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Anna") p3 = city.Citizen(name="Julia") c.add(p1, p2, p3, rel=city.hasInhabitant) p1.add(p3, rel=city.hasChild) p2.add(p3, rel=city.hasChild) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) wrapper.add(c) session.commit() with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) cs = wrapper.get(c.uid) r = session.load_by_oclass(city.City) self.assertIs(next(r), cs) r = session.load_by_oclass(city.Citizen) self.assertEqual(set(r), {p1, p2, p3}) r = session.load_by_oclass(city.Person) self.assertEqual(set(r), {p1, p2, p3}) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) cs = wrapper.get(c.uid) r = session.load_by_oclass(city.Street) self.assertRaises(StopIteration, next, r)
def test_load_by_iri(self): """Test if it is possible to load objects by their IRIs.""" c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Anna") p3 = city.Citizen(name="Julia") c.add(p1, p2, p3, rel=city.hasInhabitant) p1.add(p3, rel=city.hasChild) p2.add(p3, rel=city.hasChild) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) wrapper.add(c) session.commit() with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) cs = wrapper.get(c.uid) r = session.load_from_iri(cs.iri) self.assertIs(next(r), cs) r = session.load_from_iri(p1.iri, p2.iri, p3.iri) self.assertEqual(set(r), {p1, p2, p3}) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) cs = wrapper.get(c.uid) r = session.load_from_iri(iri_from_uid(uuid.UUID(int=1))) self.assertEqual(set(r), {None})
def test_clear_database(self): """Test clearing the database.""" # db is empty (no error occurs) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) session._clear_database() with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) wrapper.session.commit() session._clear_database() # db is not empty c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Anna") p3 = city.Citizen(name="Julia") c.add(p1, p2, p3, rel=city.hasInhabitant) p1.add(p3, rel=city.hasChild) p2.add(p3, rel=city.hasChild) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) wrapper.add(c) session.commit() session._clear_database() check_db_cleared(self, DB)
def test_init(self): """Test if first level of children are loaded automatically.""" c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Anna") p3 = city.Citizen(name="Julia") c.add(p1, p2, p3, rel=city.hasInhabitant) p1.add(p3, rel=city.hasChild) p2.add(p3, rel=city.hasChild) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) wrapper.add(c) session.commit() with TransportSessionClient(SqliteSession, URI, path=DB) \ as session: wrapper = city.CityWrapper(session=session) self.assertEqual(set(session._registry.keys()), {c.uid, wrapper.uid}) self.assertEqual(wrapper.get(c.uid).name, "Freiburg") self.assertEqual( session._registry.get(c.uid)._neighbors[city.hasInhabitant], {p1.uid: p1.oclasses, p2.uid: p2.oclasses, p3.uid: p3.oclasses}) self.assertEqual( session._registry.get(c.uid)._neighbors[city.isPartOf], {wrapper.uid: wrapper.oclasses})
def test_download(self): """Test full download routine.""" with TransportSessionClient( SqliteSession, URI, file_destination=None ) as session: images = self.setup_buffers1(session) session.commit() with TransportSessionClient( SqliteSession, URI, file_destination=CLIENT_DIR ) as session: city.CityWrapper(session=session) session.load(images[0].uid) session.load(images[1].uid) session.load(images[2].uid) self.assertEqual(set(os.listdir(CLIENT_DIR)), {FILES[0], FILES[2]}) # download again and check that no errors occur # and that the duplicates are still # in the download folder (and not more) number_of_downloaded_files = len(os.listdir(CLIENT_DIR)) with TransportSessionClient( SqliteSession, URI, file_destination=CLIENT_DIR ) as session: city.CityWrapper(session=session) session.load(images[0].uid) session.load(images[1].uid) session.load(images[2].uid) self.assertEqual( number_of_downloaded_files, len(os.listdir(CLIENT_DIR)) )
def test_vector(self): """Test capabilities to store vectors.""" c = city.City(name="Frankfurt", coordinates=[42, 24]) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) wrapper.add(c) wrapper.session.commit() with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) cw = wrapper.get(c.uid) np.testing.assert_array_equal(cw.coordinates, [42, 24])
def setUp(self): """Start the timer and fill the database.""" if not RUN_PERFORMANCE_TEST: return self.iterations = 1000 with SqliteSession(DB) as session: w = city.CityWrapper(session=session) self.fill_db(w, random_uid=False) session.commit() self.session = SqliteSession(DB) self.w = city.CityWrapper(session=self.session) gc.collect() self.start = time.time()
def test_buffers(self): """Test if the buffers work correctly.""" session = TestWrapperSession() self.assertEqual( session._buffers, [[dict(), dict(), dict()], [dict(), dict(), dict()]]) w = city.CityWrapper(session=session) c = city.City(name="city 1") n = city.Neighborhood(name="neighborhood") cw = w.add(c) cw.add(n) cw.remove(n.uid) cw.name = "city 2" w.session.prune() self.assertEqual(session._buffers, [[{ cw.uid: cw, w.uid: w }, dict(), dict()], [dict(), dict(), dict()]]) w.session._reset_buffers(BufferContext.USER) c2 = city.City(name="city3") w.add(c2) cw2 = w.get(c2.uid) w.remove(cw.uid) w.session.prune() self.assertEqual(session._buffers, [[{ cw2.uid: cw2 }, { w.uid: w }, { cw.uid: cw }], [dict(), dict(), dict()]])
def test_delete_cuds_object(self): """Tests the pruning method.""" with TestWrapperSession() as session: w = city.CityWrapper(session=session) cities = list() neighborhoods = list() for i in range(2): c = city.City(name="city %s" % i) for j in range(2): n = city.Neighborhood(name="neighborhood %s %s" % (i, j)) c.add(n) cities.append(w.add(c)) neighborhoods.extend(cities[-1].get()) session._reset_buffers(BufferContext.USER) session.delete_cuds_object(cities[0]) self.maxDiff = None self.assertEqual( session._buffers, [ [ {}, { w.uid: w, neighborhoods[0].uid: neighborhoods[0], neighborhoods[1].uid: neighborhoods[1], }, {cities[0].uid: cities[0]}, ], [{}, {}, {}], ], ) self.assertNotIn(cities[0], session._registry) self.assertRaises(AttributeError, getattr, cities[0], "name")
def test_import_rdf(self): """Test the import rdf functionality.""" with TestWrapperSession() as session: city.CityWrapper(session=session) g = json_to_rdf(CUDS_LIST_NON_PARTITIONED, rdflib.Graph()) cuds_objects = import_rdf(g, session, BufferContext.USER) self.assertEqual(len(cuds_objects), 4) self.assertEqual( set(map(lambda x: x.oclass, cuds_objects)), {city.Person, city.City, city.Citizen}, ) self.assertEqual( set(map(lambda x: x.uid.int, cuds_objects)), {1, 2, 3, 123} ) self.assertEqual( set(session._buffers[0][0]), { uuid.UUID(int=1), uuid.UUID(int=2), uuid.UUID(int=3), uuid.UUID(int=123), }, ) self.assertEqual(session._buffers[0][1:], [{}, {}]) self.assertEqual(session._buffers[1], [{}, {}, {}])
def test_expiring(self): """Test expring CUDS objects.""" c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Anna") p3 = city.Citizen(name="Julia") c.add(p1, p2, p3, rel=city.hasInhabitant) p1.add(p3, rel=city.hasChild) p2.add(p3, rel=city.hasChild) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) cw = wrapper.add(c) p1w, p2w, p3w = cw.get(p1.uid, p2.uid, p3.uid) session.commit() # p1w is no longer expired after the following assert self.assertEqual(p1w.name, "Peter") self.assertEqual(p2w.name, "Anna") update_db(DB, c, p1, p2, p3) self.assertEqual(p2w.name, "Anna") self.assertEqual(cw.name, "Paris") # expires outdated neighbor p2w self.assertEqual(p2w.name, "Jacob") self.assertEqual(p1w.name, "Peter") session.expire_all() self.assertEqual(p1w.name, "Maria") self.assertEqual(set(cw.get()), {p1w}) self.assertEqual(p2w.get(), list()) self.assertFalse(hasattr(p3w, "name")) self.assertNotIn(p3w.uid, session._registry)
def test_expiring(self): """Test expiring with transport + db session.""" c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Anna") p3 = city.Citizen(name="Julia") c.add(p1, p2, p3, rel=city.hasInhabitant) p1.add(p3, rel=city.hasChild) p2.add(p3, rel=city.hasChild) with TransportSessionClient(SqliteSession, URI, path=DB)\ as session: wrapper = city.CityWrapper(session=session) cw = wrapper.add(c) p1w, p2w, p3w = cw.get(p1.uid, p2.uid, p3.uid) session.commit() # p1w is no longer expired after the following assert self.assertEqual(p1w.name, "Peter") update_db(DB, c, p1, p2, p3) self.assertEqual(cw.name, "Paris") self.assertEqual(p1w.name, "Peter") session.expire_all() self.assertEqual(p1w.name, "Maria") self.assertEqual(set(cw.get()), {p1w}) self.assertEqual(p2w.get(), list()) self.assertFalse(hasattr(p3w, "name")) self.assertNotIn(p3w.uid, session._registry)
def setup_buffers2(self, session): """Set up the buffers for the tests below.""" wrapper = city.CityWrapper(session=session, uid=42) images = wrapper.add(city.Image(path=FILE_PATHS[0], uid=1), city.Image(path=FILE_PATHS[1], uid=2)) session._reset_buffers(BufferContext.USER) return images
def test_refresh(self): """Test refreshing CUDS objects.""" c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Anna") p3 = city.Citizen(name="Julia") c.add(p1, p2, p3, rel=city.hasInhabitant) p1.add(p3, rel=city.hasChild) p2.add(p3, rel=city.hasChild) with TransportSessionClient(SqliteSession, URI, path=DB) \ as session: wrapper = city.CityWrapper(session=session) cw = wrapper.add(c) p1w, p2w, p3w = cw.get(p1.uid, p2.uid, p3.uid) session.commit() self.assertEqual(cw.name, "Freiburg") self.assertEqual(p1w.name, "Peter") self.assertEqual(p2w.name, "Anna") self.assertEqual(p3w.name, "Julia") self.assertEqual(session._expired, {wrapper.uid}) update_db(DB, c, p1, p2, p3) session.refresh(cw, p1w, p2w, p3w) self.assertEqual(cw.name, "Paris") self.assertEqual(p1w.name, "Maria") self.assertEqual(set(cw.get()), {p1w}) self.assertEqual(p2w.get(), list()) self.assertFalse(hasattr(p3w, "name")) self.assertNotIn(p3w.uid, session._registry)
def test_run_command(self): """Test to run a command.""" correct = False # command to be executed def command(s, uid, name): nonlocal correct added = s._buffers[BufferContext.USER][BufferType.ADDED] correct = set(added.keys()) == {uuid.UUID(int=2)} and \ added[uuid.UUID(int=2)].name == "Paris" s._reset_buffers(BufferContext.USER) added = s._buffers[BufferContext.ENGINE][BufferType.ADDED] added[uuid.UUID(int=uid)] = city.City(name=name, uid=uid) TestWrapperSession.command = consumes_buffers(command) server = TransportSessionServer(TestWrapperSession, None, None) with TestWrapperSession() as s1: # initialize buffers ws1 = city.CityWrapper(session=s1, uid=123) c = city.City(name="Freiburg", uid=1) ws1.add(c) s1._reset_buffers(BufferContext.USER) # test the method server.session_objs = {"1": s1, "2": 123} result = server._run_command(json.dumps(SERIALIZED_BUFFERS), "command", "1") self.assertTrue(correct) self.assertEqual(json.loads(result[0]), SERIALIZED_BUFFERS2) self.assertEqual(result[1], [])
def test_handle_request(self): """Test if error message is returned when invalid command is given.""" def command(s, age, name): raise RuntimeError("Something went wrong: %s, %s" % (age, name)) TestWrapperSession.command = command server = TransportSessionServer(TestWrapperSession, None, None) with TestWrapperSession() as s1: # initialize buffers ws1 = city.CityWrapper(session=s1, uid=123) c = city.City(name="Freiburg", uid=1) ws1.add(c) s1._reset_buffers(BufferContext.USER) # test server.session_objs["user1"] = s1 self.assertEqual( server.handle_request(command="run", data=SERIALIZED_BUFFERS, connection_id="user1", temp_directory=None), ("ERROR: Invalid command", [])) self.assertEqual( server.handle_request(command="command", data=json.dumps(SERIALIZED_BUFFERS), connection_id="user1", temp_directory=None), ("ERROR: RuntimeError: Something went wrong: 42, London", []))
def test_fix_old_neighbors(self): """Check if _fix_old_neighbors. - Deletes old children. - Adds connection to old parents. """ c = city.City(name="Freiburg") with CoreSession() as session: wrapper = city.CityWrapper(session=session) cw = wrapper.add(c) n = city.Neighborhood(name="Zähringen") nw = cw.add(n) c = clone_cuds_object(c) c._session = session old_neighbor_diff = get_neighbor_diff(cw, c) old_neighbors = session.load(*[x[0] for x in old_neighbor_diff]) Cuds._fix_old_neighbors( new_cuds_object=c, old_cuds_object=cw, old_neighbors=old_neighbors, old_neighbor_diff=old_neighbor_diff, ) self.assertEqual(c.get(rel=city.isPartOf), [wrapper]) self.assertEqual(c.get(rel=city.hasPart), []) self.assertEqual(nw.get(rel=city.isPartOf), []) self.assertEqual(wrapper.get(rel=city.hasPart), [c])
def test_recursive_store(self): """Test if _recursive_store correctly stores cuds_objects correctly. It should correct dangling and one-way connections. """ c = city.City(name="Freiburg") p1 = city.Citizen() p2 = city.Citizen() p3 = city.Citizen() p4 = city.Citizen() with CoreSession() as session: w = city.CityWrapper(session=session) cw = w.add(c) c.add(p1, p2, p3, rel=city.hasInhabitant) p3.add(p1, p2, rel=city.isChildOf) p3.add(p4, rel=city.hasChild) cw = w._recursive_store(c, cw) p1w, p2w, p3w = cw.get(p1.uid, p2.uid, p3.uid) p4w = p3w.get(p4.uid) self.assertEqual(w.get(rel=city.hasPart), [cw]) self.assertEqual(set(cw.get(rel=city.hasInhabitant)), {p1w, p2w, p3w}) self.assertEqual(set(cw.get(rel=city.isPartOf)), {w}) self.assertEqual(p3w.get(rel=city.INVERSE_OF_hasInhabitant), [cw]) self.assertEqual(set(p3w.get(rel=city.isChildOf)), {p1w, p2w}) self.assertEqual(p3w.get(rel=city.hasChild), [p4w])
def test_delete_cuds_object_recursively(self): """Test the delete_cuds_object_recursively function.""" with TestWrapperSession() as session: wrapper = city.CityWrapper(session=session) a = city.City(name="freiburg", session=session) b = city.Citizen(name="peter", session=session) branch(wrapper, branch(a, b, rel=city.hasInhabitant)) self.maxDiff = None session._reset_buffers(BufferContext.USER) delete_cuds_object_recursively(a) self.assertEqual( session._buffers, [ [{}, { wrapper.uid: wrapper }, { a.uid: a, b.uid: b }], [{}, {}, {}], ], ) self.assertEqual(wrapper.get(rel=cuba.relationship), []) self.assertEqual(a.get(rel=cuba.relationship), []) self.assertEqual(b.get(rel=cuba.relationship), [])
def test_auth(self): """Test authentication.""" with TransportSessionClient(AuthSession, URI_CORRECT1, path=DB) as session: city.CityWrapper(session=session) with TransportSessionClient(AuthSession, URI_WRONG1, path=DB) as session: self.assertRaises(RuntimeError, city.CityWrapper, session=session) with TransportSessionClient(SimpleAuthSession, URI_CORRECT2, path=DB) as session: city.CityWrapper(session=session) with TransportSessionClient(SimpleAuthSession, URI_WRONG2, path=DB) as session: self.assertRaises(RuntimeError, city.CityWrapper, session=session)
def test_cuds_with_iri(self): """Try to assign IRIs as UIDs for CUDS objects.""" c = city.City( name="Freiburg", iri="http://example.org/namespace" "#Freiburg" ) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) wrapper.add(c) session.commit() with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) self.assertEqual( set(session._registry.keys()), {c.uid, wrapper.uid} ) self.assertEqual(wrapper.get(c.uid).name, "Freiburg") self.assertEqual(wrapper.get(c.uid).oclass, city.City)
def test_create_recycle(self): """Test creation of cuds_objects for different session.""" default_session = CoreSession() osp.core.cuds.Cuds._session = default_session a = city.City(name="Freiburg") self.assertIs(a.session, default_session) with TestWrapperSession() as session: w = city.CityWrapper(session=session) with EngineContext(session): b = create_recycle(oclass=city.City, kwargs={"name": "Offenburg"}, uid=a.uid, session=session, fix_neighbors=False) self.assertEqual(b.name, "Offenburg") self.assertEqual(b.uid, a.uid) self.assertEqual(set(default_session._registry.keys()), {a.uid}) self.assertIs(default_session._registry.get(a.uid), a) self.assertEqual(set(session._registry.keys()), {b.uid, w.uid}) self.assertIs(session._registry.get(b.uid), b) self.assertEqual(session._buffers, [[{ w.uid: w }, dict(), dict()], [{ b.uid: b }, dict(), dict()]]) x = city.Citizen() x = b.add(x, rel=city.hasInhabitant) c = create_recycle(oclass=city.City, kwargs={"name": "Emmendingen"}, session=session, uid=a.uid, fix_neighbors=False) self.assertIs(b, c) self.assertEqual(c.name, "Emmendingen") self.assertEqual(c.get(rel=cuba.relationship), []) self.assertNotEqual(x.get(rel=cuba.relationship), []) self.assertEqual(set(default_session._registry.keys()), {a.uid, x.uid}) self.assertIs(default_session._registry.get(a.uid), a) self.assertEqual(session._buffers, [[{ w.uid: w, x.uid: x }, { c.uid: c }, dict()], [dict(), dict(), dict()]]) x = city.Citizen() x = c.add(x, rel=city.hasInhabitant) c = create_recycle(oclass=city.City, kwargs={"name": "Karlsruhe"}, session=session, uid=a.uid, fix_neighbors=True) self.assertEqual(x.get(rel=cuba.relationship), [])
def test_load_missing(self): """Test if missing objects are loaded automatically.""" c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Anna") p3 = city.Citizen(name="Julia") c.add(p1, p2, p3, rel=city.hasInhabitant) p1.add(p3, rel=city.hasChild) p2.add(p3, rel=city.hasChild) with SqliteSession(DB) as session: wrapper = city.CityWrapper(session=session) wrapper.add(c) session.commit() with TransportSessionClient(SqliteSession, URI, path=DB) as session: wrapper = city.CityWrapper(session=session) self.assertEqual(set(session._registry.keys()), {c.uid, wrapper.uid}) cw = wrapper.get(c.uid) p1w = cw.get(p1.uid) p2w = cw.get(p2.uid) p3w = p1w.get(p3.uid) self.assertEqual( set(session._registry.keys()), {c.uid, wrapper.uid, p1.uid, p2.uid, p3.uid}, ) self.assertEqual(p1w.name, "Peter") self.assertEqual(p2w.name, "Anna") self.assertEqual(p3w.name, "Julia") self.assertEqual( p3w._neighbors[city.isChildOf], { p1.uid: p1.oclasses, p2.uid: p2.oclasses }, ) self.assertEqual(p2w._neighbors[city.hasChild], {p3.uid: p3.oclasses}) self.assertEqual( p2w._neighbors[city.INVERSE_OF_hasInhabitant], {c.uid: c.oclasses}, )
def test_clone_cuds_object(self): """Test cloning of cuds.""" a = city.City(name="Freiburg") with CoreSession() as session: w = city.CityWrapper(session=session) aw = w.add(a) clone = clone_cuds_object(aw) self.assertIsNot(aw, None) self.assertIs(clone.session, aw.session) self.assertEqual(clone.uid, aw.uid) self.assertIs(aw, session._registry.get(aw.uid)) self.assertEqual(clone.name, "Freiburg")
def setup_buffers1(self, session): """Set up the buffers for the tests below.""" wrapper = city.CityWrapper(session=session) images = wrapper.add( city.Image(path=FILE_PATHS[0]), city.Image(path=FILE_PATHS[1]) ) session._reset_buffers(BufferContext.USER) wrapper.remove(images[1].uid) images[0].path = FILE_PATHS[0] images = list(images) + [wrapper.add(city.Image(path=FILE_PATHS[2]))] session.prune() return images
def test_multiple_users(self): """Test what happens if multiple users access the database.""" with SqliteSession(DB) as session1: wrapper1 = city.CityWrapper(session=session1) city1 = city.City(name="Freiburg") wrapper1.add(city1) session1.commit() with SqliteSession(DB) as session2: wrapper2 = city.CityWrapper(session=session2) wrapper2.add(city.City(name="Offenburg")) session2.commit() cw = wrapper1.add(city.City(name="Karlsruhe")) self.assertEqual(session1._expired, {city1.uid}) self.assertEqual(session1._buffers, [[{ cw.uid: cw }, { wrapper1.uid: wrapper1 }, dict()], [dict(), dict(), dict()]]) session1.commit()
def test_insert(self): """Test inserting in the sqlite table.""" c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Georg") c.add(p1, p2, rel=city.hasInhabitant) with DataspaceSession(URI) as session: wrapper = city.CityWrapper(session=session) wrapper.add(c) session.commit() check_state(self, c, p1, p2, db=DB)
def test_add_twice(self): """Test what happens if you add the same object twice.""" p = city.Citizen(name="Ralf") c1 = city.City(name="Freiburg") c2 = city.City(name="Offenburg") with CoreSession() as session: w = city.CityWrapper(session=session) c1w, c2w = w.add(c1, c2) pw1 = c1w.add(p, rel=city.hasInhabitant) pw2 = c2w.add(p, rel=city.hasInhabitant) self.assertIs(pw1, pw2) self.assertEqual(set(pw1.get(rel=city.INVERSE_OF_hasInhabitant)), {c1w, c2w})
def test_rdf_import(self): """Test the import of RDF data.""" with TestSession() as session: w = branch( city.CityWrapper(session=session), branch(city.City(name="Freiburg"), city.Neighborhood(name="Littenweiler"))) g = get_rdf_graph(session) c = w.get(rel=city.hasPart)[0] c.remove(rel=cuba.relationship) session._rdf_import(g) self.assertEqual(w.get(rel=city.hasPart), [c]) self.assertEqual(c.get(rel=city.hasPart)[0].name, "Littenweiler")
def test_load_by_oclass(self): """Load elements by ontology class via transport + db session.""" c = city.City(name="Freiburg") p1 = city.Citizen(name="Peter") p2 = city.Citizen(name="Anna") p3 = city.Citizen(name="Julia") c.add(p1, p2, p3, rel=city.hasInhabitant) p1.add(p3, rel=city.hasChild) p2.add(p3, rel=city.hasChild) with TransportSessionClient(SqliteSession, URI, path=DB) as session: wrapper = city.CityWrapper(session=session) wrapper.add(c) session.commit() with TransportSessionClient(SqliteSession, URI, path=DB) as session: wrapper = city.CityWrapper(session=session) cs = wrapper.get(c.uid) r = session.load_by_oclass(city.City) self.assertIs(next(iter(r)), cs) r = session.load_by_oclass(city.Citizen) self.assertEqual(set(r), {p1, p2, p3}) r = session.load_by_oclass(city.Person) self.assertEqual(set(r), {p1, p2, p3})