Hello Jiba!
Thanks a lot for developing & maintaining Owlready2. It's been amazingly useful!
I'm a fairly new user and still find some concepts unclear, especially when reading and writing local files. My use of Owlready2 is purely from a Knowledge Graph perspective. I'm initializing my ontology like so: o2.default_world.set_backend(filename = "quadstore.sqlite3", exclusive=True) onto = o2.get_ontology('reso.owl').load() Exporting the world workso2.default_world.save(path) Specifying the output file worksonto.save(file='reso.owl', format='rdfxml') Saving without arguments will not work>>> onto.save() --------------------------------------------------------------------------- IndexError Traceback (most recent call last) C:\(...)\Temp/ipykernel_23620/1481190103.py in <module> ----> 1 reso.db.onto.onto.save() c:\Anaconda3\lib\site-packages\owlready2\namespace.py in save(self, file, format, **kargs) 1168 def save(self, file = None, format = "rdfxml", **kargs): 1169 if file is None: -> 1170 file = _open_onto_file(self._base_iri, self.name, "wb") 1171 if _LOG_LEVEL: print("* Owlready2 * Saving ontology %s to %s..." % (self.name, getattr(file, "name", "???")), file = sys.stderr) 1172 self.graph.save(file, format, **kargs) c:\Anaconda3\lib\site-packages\owlready2\namespace.py in _open_onto_file(base_iri, name, mode, only_local) 1447 if os.path.exists(filename) and os.path.isfile(filename): return open(filename, mode) 1448 if (mode.startswith("r")) and not only_local: return urllib.request.urlopen(base_iri) -> 1449 if (mode.startswith("w")): return open(os.path.join(onto_path[0], "%s.owl" % name), mode) 1450 raise FileNotFoundError 1451 IndexError: list index out of range However if I initialize the ontology differently, this behaviour can change. It is also conditional on many parameters. For instance, if entities are added with different base uri, the following can occur: (this is not my own traceback, I encountered a similar issue and expended too much time already trying to replicate the error - will document it if I find it again : TypeError Traceback (most recent call last) <ipython-input-20-a50699e0134c> in <module> 39 filename = "raw/"+DATASET+"_"+split+".owl" 40 print(onto, len(list(onto.properties())), list(onto.properties())) ---> 41 onto.save(file = filename, format = "rdfxml") d:\Programs\Anaconda3\envs\pytorch\lib\site-packages\owlready2\namespace.py in save(self, file, format, **kargs) 1004 if _LOG_LEVEL: print("* Owlready2 * Saving ontology %s to %s..." % (self.name, file), file = sys.stderr) 1005 file = open(file, "wb") -> 1006 self.graph.save(file, format, **kargs) 1007 file.close() 1008 else: d:\Programs\Anaconda3\envs\pytorch\lib\site-packages\owlready2\driver.py in save(self, f, format, commit, **kargs) 223 def save(self, f, format = "rdfxml", commit = False, **kargs): 224 if commit: self.parent.commit() --> 225 _save(f, format, self, **kargs) 226 227 d:\Programs\Anaconda3\envs\pytorch\lib\site-packages\owlready2\driver.py in _save(f, format, graph, filter) 500 501 else: --> 502 o = _unabbreviate(o) 503 s_lines.append(""" <%s rdf:resource="%s"/>""" % (p, o)) 504 d:\Programs\Anaconda3\envs\pytorch\lib\site-packages\owlready2\driver.py in _unabbreviate(storid) 290 @lru_cache(None) 291 def _unabbreviate(storid): --> 292 r = graph._unabbreviate(storid).replace("&", "&") 293 if r.startswith(base_iri): 294 if base_iri.endswith("/"): return r[len(base_iri) :] d:\Programs\Anaconda3\envs\pytorch\lib\site-packages\owlready2\triplelite.py in _unabbreviate(self, storid) 489 490 def _unabbreviate(self, storid): --> 491 return self.execute("SELECT iri FROM resources WHERE storid=? LIMIT 1", (storid,)).fetchone()[0] 492 493 def get_storid_dict(self): TypeError: 'NoneType' object is not subscriptable" Could you provide a bit more insight into which parameters and process are best for handling local ontologies and load/save them to files? Specifically, here are a list of questions.
Thank you very much, and many cheers! |
Administrator
|
Hello,
* Saving without arguments will not work Ontology.save() without arguments requires that you specify the onto_path variable (with onto_path.append("xxx_path")). It works like PYTHON_PATH and sys.path, but for ontologies and not for Python modules). Ontology.save() without arguments will save the ontology in the directory onto_path[0], and the filename is determined by the last part of the ontology's IRI. * Why is load() required when creating an ontology? load() is required when loading an ontology from Internet or from a local file. On the contrary, it should not be called when creating an ontology from scratch in Python. * How are the base URI and ontology name used in the saving process? When saving an ontology, the IRI of the ontology is written inside the file (or the quadstore). As a consequence, you cannot just rename the OWL file to change the IRI of the ontology : the content of the file must also be changed. * Are there principles, enforced by Owlready2 or not, that dictate how IRI or individual names should be written? IRI must starts with http:// or https:// (Owlready2 accepts file:// but many tools do not). In addition, many special characters are not supported in IRI, but Owlready2 is actually quite tolerant and often accepts them. My personal recommendation are to use IRI of the form "http://website.xxx/path/ontoname.owl#entity", but other forms are acceptable and fully supported, e.g. "http://website.xxx/path/ontoname/entity". * What are the pros and cons of loading/saving ontologies VS worlds? Savings ontologies produces multiples OWL or RDF files, it is slower, but the files can be opened with other tools (like Protégé). Saving world produces a single file, is faster, but the file can only be opened with Owlready2. Jiba |
Thank you very much for all these clear answers!
Now I have some code to re-work a bit in order to leverage this new knowledge ;) |
This post was updated on .
Hi again!
I've been reformatting my code to integrate these new recommendations. However, I run into errors for the two main options I've been trying, namely setting onto_path as relative or absolute. Onto_path absolute path, saving with onto.save(path), with argument as built inside owlready2>>> # Local onto_path example >>> import owlready2 as o2 >>> o2.default_world.set_backend(filename = "quadstore.sqlite3", exclusive=True) >>> onto = o2.get_ontology('http://reso.owl') >>> path = r'C:\Users\...\reso\' >>> o2.onto_path.append(path) >>> onto.name = 'reso' >>> # Example of an individual IRI >>> document_py_handle 'http://reso.owl#document' >>> # Trying to save >>> p = os.path.join('', "%s.owl" % name) >>> onto.save(p) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) C:\...\Local\Temp/ipykernel_22096/1142227128.py in <module> ----> 1onto.save(p) c:\Anaconda3\lib\site-packages\owlready2\namespace.py in save(self, file, format, **kargs) 1175 if _LOG_LEVEL: print("* Owlready2 * Saving ontology %s to %s..." % (self.name, file), file = sys.stderr) 1176 file = open(file, "wb") -> 1177 self.graph.save(file, format, **kargs) 1178 file.close() 1179 else: c:\Anaconda3\lib\site-packages\owlready2\driver.py in save(self, f, format, commit, **kargs) 223 def save(self, f, format = "rdfxml", commit = False, **kargs): 224 if commit: self.parent.commit() --> 225 _save(f, format, self, **kargs) 226 227 c:\Anaconda3\lib\site-packages\owlready2\driver.py in _save(f, format, graph, filter) 444 445 if (p == rdf_type) and (type == "rdf:Description") and (not o < 0): --> 446 t = abbrev(o) 447 if not t in bad_types: 448 if t.startswith("#"): t = t[1:] ... --> 505 return self.execute("SELECT iri FROM resources WHERE storid=? LIMIT 1", (storid,)).fetchone()[0] 506 507 def get_storid_dict(self): TypeError: 'NoneType' object is not subscriptable Using an onto_path relative path with or witout arguments, and using an absolute path without argumentsThese 3 methods will produce a permissionError I can't explain (I could manually read or write through the same python script using "with open(, 'w') as f: f.write(...)" without any problem). >>> # Local onto_path example >>> import owlready2 as o2 >>> o2.default_world.set_backend(filename = "quadstore.sqlite3", exclusive=True) >>> onto = o2.get_ontology('http://reso.owl') >>> o2.onto_path.append('/') >>> onto.name = 'reso' >>> # Example of an individual IRI >>> document_py_handle 'http://reso.owl#document' >>> # Trying to save >>> onto.save() --------------------------------------------------------------------------- PermissionError Traceback (most recent call last) C:\...\Temp/ipykernel_28748/1481190103.py in <module> ----> 1onto.save() c:\Anaconda3\lib\site-packages\owlready2\namespace.py in save(self, file, format, **kargs) 1168 def save(self, file = None, format = "rdfxml", **kargs): 1169 if file is None: -> 1170 file = _open_onto_file(self._base_iri, self.name, "wb") 1171 if _LOG_LEVEL: print("* Owlready2 * Saving ontology %s to %s..." % (self.name, getattr(file, "name", "???")), file = sys.stderr) 1172 self.graph.save(file, format, **kargs) c:\Anaconda3\lib\site-packages\owlready2\namespace.py in _open_onto_file(base_iri, name, mode, only_local) 1447 if os.path.exists(filename) and os.path.isfile(filename): return open(filename, mode) 1448 if (mode.startswith("r")) and not only_local: return urllib.request.urlopen(base_iri) -> 1449 if (mode.startswith("w")): return open(os.path.join(onto_path[0], "%s.owl" % name), mode) 1450 raise FileNotFoundError 1451 PermissionError: [Errno 13] Permission denied: '/reso.owl' So I though I was following better guidelines but I instead encounter a loss of functionality, with the only saving mechanism working being to and from the sqlite database. However I'd need to make an actual, rdfxml, file saving work. Have you any insight on what I am doing wrong? --------------------------------------------------------------------------------------------------- EDIT: Here is a longer traceback for easier tracking --------------------------------------------------------------------------- TypeError Traceback (most recent call last) C:\...\Temp/ipykernel_29208/2232994153.py in <module> ----> 1 reso.db.onto.save() c:\...\onto.py in save() 123 name = onto.name 124 p = os.path.join('', "%s.owl" % name) --> 125 onto.save(p) 126 127 def world_to_rdf(path:str): c:\Anaconda3\lib\site-packages\owlready2\namespace.py in save(self, file, format, **kargs) 1175 if _LOG_LEVEL: print("* Owlready2 * Saving ontology %s to %s..." % (self.name, file), file = sys.stderr) 1176 file = open(file, "wb") -> 1177 self.graph.save(file, format, **kargs) 1178 file.close() 1179 else: c:\Anaconda3\lib\site-packages\owlready2\driver.py in save(self, f, format, commit, **kargs) 223 def save(self, f, format = "rdfxml", commit = False, **kargs): 224 if commit: self.parent.commit() --> 225 _save(f, format, self, **kargs) 226 227 c:\Anaconda3\lib\site-packages\owlready2\driver.py in _save(f, format, graph, filter) 444 445 if (p == rdf_type) and (type == "rdf:Description") and (not o < 0): --> 446 t = abbrev(o) 447 if not t in bad_types: 448 if t.startswith("#"): t = t[1:] c:\Anaconda3\lib\site-packages\owlready2\driver.py in abbrev(storid) 316 @lru_cache(None) 317 def abbrev(storid): --> 318 x = graph._unabbreviate(storid).replace("&", "&") 319 320 splitat = max(x.rfind("/"), x.rfind("#"), x.rfind(":")) c:\Anaconda3\lib\site-packages\owlready2\triplelite.py in _unabbreviate(self, storid) 503 504 def _unabbreviate(self, storid): --> 505 return self.execute("SELECT iri FROM resources WHERE storid=? LIMIT 1", (storid,)).fetchone()[0] 506 507 def get_storid_dict(self): TypeError: 'NoneType' object is not subscriptable |
Administrator
|
Hi,
For the second problem, the cause is that you set "/" as the onto path. Thus, Owlready will try to save the ontology in the / directory. But either you are using Linux (or Mac) and / is only available for root user, or you are using Windows and / does not exist (it is more or less equivalent to C:/). You need to specify a writeable directory in onto_path if you want to save ontology. For the first problem, the path is writeable (but notice that the path variable is actually not used, since it is not used in the construction of the p variable later). The problem seems related to the translation in RDF/XML ; Owlready encounter an entity for which it cannot find an IRI. If you send me the ontology, I can investigate it further. Jiba |
Free forum by Nabble | Edit this page |