Changeset 94
- Timestamp:
- 02/05/08 22:22:57 (4 years ago)
- Location:
- rdfalchemy/trunk
- Files:
-
- 2 added
- 7 modified
-
rdfalchemy/descriptors.py (modified) (7 diffs)
-
rdfalchemy/engine/__init__.py (modified) (1 diff)
-
rdfalchemy/rdfalchemy.py (modified) (11 diffs)
-
rdfalchemy/samples/example.py (modified) (1 diff)
-
rdfalchemy/sesame2.py (modified) (2 diffs)
-
rdfalchemy/sparql.py (modified) (8 diffs)
-
setup.py (modified) (1 diff)
-
test/company_test.py (added)
-
test/delete_test.py (added)
Legend:
- Unmodified
- Added
- Removed
-
rdfalchemy/trunk/rdfalchemy/descriptors.py
r91 r94 65 65 """suitable for a triple takes a value and returns a Literal, URIRef or BNode 66 66 suitable for a triple""" 67 if isinstance(value,Identifier): 67 if isinstance(value, rdfSubject): 68 return value.resUri 69 elif isinstance(value, Identifier): 68 70 return value 69 71 else: … … 143 145 obj.__dict__[self.name]= value 144 146 o =value2object(value) 145 obj.db.set((obj , self.pred, o))147 obj.db.set((obj.resUri, self.pred, o)) 146 148 #return None 147 149 … … 185 187 for value in oldvals: 186 188 if value not in newvals: 187 obj.db.remove((obj ,self.pred, value2object(value)))189 obj.db.remove((obj.resUri,self.pred, value2object(value))) 188 190 log.debug("removing: %s, %s, %s"%(obj.n3(),self.pred,value)) 189 191 for value in newvals: 190 192 if value not in oldvals: 191 obj.db.add((obj , self.pred, value2object(value)))193 obj.db.add((obj.resUri, self.pred, value2object(value))) 192 194 log.debug("adding: %s, %s, %s"%(obj.n3(),self.pred,value)) 193 195 obj.__dict__[self.name] = copy(newvals) … … 234 236 oldvals = [] 235 237 obj.__dict__[self.name] = oldvals 236 oldhead = obj.db.value(obj ,self.pred)238 oldhead = obj.db.value(obj.resUri,self.pred) 237 239 ## # This is a stack style where retrevial is oppisite of how it starts out 238 240 ## newnode = RDF.nil … … 255 257 newtail = BNode() 256 258 obj.db.add((oldtail, RDF.rest, RDF.nil)) 257 obj.db.set((obj , self.pred, newhead))259 obj.db.set((obj.resUri, self.pred, newhead)) 258 260 if oldhead: 259 261 rdfSubject(oldhead)._remove(db=obj.db) … … 278 280 #log.debug("Geting %s for %s"%(obj.db.qname(self.pred),obj.db.qname(obj.resUri))) 279 281 log.debug("Geting %s for %s"%(self.pred,obj.n3())) 280 base = obj.db.value(obj , self.pred)282 base = obj.db.value(obj.resUri, self.pred) 281 283 if not base: 282 284 return [] … … 299 301 if not isinstance(newvals, list): 300 302 raise AttributeError("to set a rdflibList you must pass in a list (it can be a list of one)") 301 seq = obj.db.value(obj , self.pred)303 seq = obj.db.value(obj.resUri, self.pred) 302 304 if not seq: 303 305 seq = BNode() 304 obj.db.add((obj , self.pred, seq))306 obj.db.add((obj.resUri, self.pred, seq)) 305 307 obj.db.add((seq, RDF.type, RDF.Seq)) 306 308 for s,p,o in obj.db.triples((seq, None, None)): -
rdfalchemy/trunk/rdfalchemy/engine/__init__.py
r91 r94 8 8 rdflib ConjunctiveGraph 9 9 e.g.: 10 create_engine('mysql://myname@localhost/rdflibdb') 11 create_engine('sleepycat://~/working/rdf_db') 12 create_engine('zodb:///var/rdflib/Data.fs') 13 create_engine('zodb://localhost:8672') 10 11 - create_engine('mysql://myname@localhost/rdflibdb') 12 - create_engine('sleepycat://~/working/rdf_db') 13 - create_engine('zodb:///var/rdflib/Data.fs') 14 - create_engine('zodb://localhost:8672') 15 14 16 for zodb: 17 15 18 the key in the Zope database is hardcoded as 'rdflib' 16 19 urls ending in `.fs` indicate FileStorage -
rdfalchemy/trunk/rdfalchemy/rdfalchemy.py
r92 r94 68 68 69 69 #class rdfSubject(object): 70 class rdfSubject( Identifier):70 class rdfSubject(object): 71 71 db=ConjunctiveGraph() 72 72 """Default graph for access to instances of this type""" 73 73 rdf_type=None 74 74 """rdf:type of instances of this class""" 75 def __new__(cls, resUri = None, **kwargs): 76 """docstring for __new__""" 77 if not resUri or isinstance(resUri, BNode): 78 sub = BNode.__new__(cls, resUri) 79 sub.node_type = 'bnode' 80 elif isinstance(resUri, (str, unicode)) and resUri.startswith("_:"): 81 sub = BNode.__new__(cls, resUri[2:]) 82 sub.node_type = 'bnode' 83 elif isinstance(resUri, URIRef): 84 sub = URIRef.__new__(cls, resUri) 85 sub.node_type = 'uri' 86 elif isinstance(resUri, (str, unicode)) and resUri[0]=="<" and resUri[-1]==">": 87 sub = URIRef.__new__(cls, resUri[1:-1]) 88 sub.node_type = 'uri' 75 ## 76 ## def __new__(cls, resUri = None, **kwargs): 77 ## obj = object.__new__(cls) 78 ## obj.resUri = resUri 79 ## return obj.__init__(resUri, **kwargs) 80 81 82 def __init__(self, resUri = None, **kwargs): 83 """The constructor tries hard to do return you an rdfSubject 84 85 :param resUri: can be one of 86 87 * an instance of an rdfSubject 88 * an instance of a BNode or a URIRef 89 * an n3 uriref string like: <urn:isbn:1234567890> 90 * an n3 bnode string like _:xyz1234 91 92 :param resUri: if None then create an instance with a BNode resUri 93 :param kwargs: is a set of values that will be set using the keys to find the appropriate descriptor""" 94 95 if not resUri: 96 self.resUri = BNode() 97 if self.rdf_type: 98 self.db.add((self.resUri,RDF.type,self.rdf_type)) 99 elif isinstance(resUri, (BNode, URIRef)): 100 self.resUri=resUri 89 101 elif isinstance(resUri, rdfSubject): 90 sub = Identifier.__new__(cls, resUri) 91 sub.node_type = resUri.node_type 92 if sub.db != resUri.db: 93 sub.db = resUri.db 102 self.resUri=resUri.resUri 103 self.db=resUri.db 104 elif instance(resUri, (str, unicode)): 105 if resUri[0]=="<" and resUri[-1]==">": 106 self.resUri=URIRef(resUri[1:-1]) 107 elif resUri.startswith("_:"): 108 self.resUri=BNode(resUri[2:]) 94 109 else: 95 110 raise AttributeError("cannot construct rdfSubject from %s"%(str(resUri))) 96 return sub 97 98 def __init__(self, resUri = None, **kwargs): 99 """The constructor tries hard to do return you an rdfSubject 100 the parameter resUri can be: 101 * an instance of an rdfSubject 102 * an instance of a BNode or a URIRef 103 * an n3 uriref string like: <urn:isbn:1234567890> 104 * an n3 bnode string like _:xyz1234 105 a null resUri will cause a new one created of 106 this classes rdf_type 107 `kwargs` is a set of values that will be set""" 111 108 112 if kwargs: 109 113 self._set_with_dict(kwargs) … … 112 116 # lets create a new one 113 117 if self.rdf_type: 114 self.db.set((self ,RDF.type, self.rdf_type))118 self.db.set((self.resUri,RDF.type, self.rdf_type)) 115 119 # lets get a default namespace for this 116 120 # ??obsolete ??? 117 rdftype = list(self.db.objects(self , RDF.type))121 rdftype = list(self.db.objects(self.resUri, RDF.type)) 118 122 if len(rdftype)==1: 119 123 self.namespace, trash = re_ns_n.match(rdftype[0]).groups() 120 124 self.namespace=Namespace(self.namespace) 121 elif isinstance(self ,URIRef):122 ns_n = re_ns_n.match(self )125 elif isinstance(self.resUri, URIRef): 126 ns_n = re_ns_n.match(self.resUri) 123 127 if ns_n: 124 128 self.namespace, self.name = ns_n.groups() … … 127 131 def n3(self): 128 132 """n3 repr of this node""" 129 if self.node_type == 'bnode': 130 return "_:%s"%self 131 elif self.node_type == 'uri': 132 return "<%s>"%self 133 else: 134 raise AttributeError("Unknown node type for %s"(self)) 133 return self.resUri.n3() 135 134 136 135 … … 158 157 class. 159 158 example: 159 160 160 bigBlue = Company.get_by(symbol='IBM') 161 161 162 OWLNote:162 :Note: 163 163 the keyword should map to an rdf predicate 164 164 that is of type owl:InverseFunctional""" … … 234 234 #log.debug("Getting with __getitem__ %s for %s"%(self.db.qname(pred),self.db.qname(self.resUri))) 235 235 log.debug("Getting with __getitem__ %s for %s"%(pred,self.n3())) 236 val=self.db.value(self ,pred)236 val=self.db.value(self.resUri, pred) 237 237 if isinstance(val,Literal): 238 238 val = val.toPython() … … 247 247 #log.debug("Deleting with __delitem__ %s for %s"%(self.db.qname(pred),self.db.qname(self.resUri))) 248 248 log.debug("Deleting with __delitem__ %s for %s"%(pred,self)) 249 for s,p,o in self.db.triples((self , pred, None)):249 for s,p,o in self.db.triples((self.resUri, pred, None)): 250 250 self.db.remove((s,p,o)) 251 251 #finally if the object in the triple was a bnode 252 252 #cascade delete the thing it referenced 253 253 # ?? FIXME Do we really want to cascade if it's an rdfSubject?? 254 if isinstance(o, BNode) or isinstance(o,rdfSubject) and o.node_type == 'bnode':254 if isinstance(o, (BNode, rdfSubject)): 255 255 rdfSubject(o)._remove(db=self.db,cascade='bnode') 256 256 257 257 def _set_with_dict(self, kv): 258 """for each key,value pair in dict kv 259 set self.key = value""" 258 """ 259 :param kv: a dict :: 260 261 for each key,value pair in dict kv 262 set self.key = value 263 264 """ 260 265 for key,value in kv.items(): 261 266 #item.__class__._getdescriptor('authors').__get__(item, item.__class__) … … 264 269 265 270 266 def _remove(self, node=None,db=None, cascade = 'bnode', bnodeCheck=True):271 def _remove(self, db=None, cascade = 'bnode', bnodeCheck=True): 267 272 """remove all triples where this rdfSubject is the subject of the triple 268 db -- limit the remove operation to this graph 269 node -- node to remove from the graph defaults to self 270 cascade -- must be one of: 271 * none -- remove none 273 274 :param db: limit the remove operation to this graph 275 :param cascade: must be one of: 276 277 * none -- remove none 272 278 * bnode -- (default) remove all unreferenced bnodes 273 279 * all -- remove all unreferenced bnode(s) AND uri(s) 274 bnodeCheck -- boolean 280 281 :param bnodeCheck: boolean 282 275 283 * True -- (default) check bnodes and raise exception if there are 276 still references to this node277 * False -- do not check. This can leave orphaned object reference278 in triples. Use only if you are resetting the value in279 the same transaction284 still references to this node 285 * False -- do not check. This can leave orphaned object reference 286 in triples. Use only if you are resetting the value in 287 the same transaction 280 288 """ 281 if not node: 282 node = self 283 log.debug("Called remove on %s" % node) 289 noderef = self.resUri 290 log.debug("Called remove on %s" % self) 284 291 if not db: 285 292 db = self.db 293 286 294 # we cannot delete a bnode if it is still referenced, 287 295 # i.e. if it is the o of a s,p,o 288 296 if bnodeCheck: 289 if isinstance(node ,BNode) or isinstance(node,rdfSubject) and node.node_type=='bnode':290 for s,p,o in db.triples((None,None,node )):291 raise RDFAlchemyError("Cannot delete a bnode %s becuase %s still references it" % (node .n3(), s.n3()))297 if isinstance(noderef ,BNode): 298 for s,p,o in db.triples((None,None,noderef)): 299 raise RDFAlchemyError("Cannot delete a bnode %s becuase %s still references it" % (noderef.n3(), s.n3())) 292 300 # determine an appropriate test for cascade decisions 293 301 if cascade == 'bnode': 294 302 #we cannot delete a bnode if there are still references to it 295 303 def test(node): 296 if isinstance(node,(URIRef,Literal)) \ 297 or isinstance(node,rdfSubject) and node.node_type <> 'bnode': 304 if isinstance(node,(URIRef,Literal)): 298 305 return False 299 306 for s,p,o in db.triples((None,None,node)): … … 305 312 elif cascade == 'all': 306 313 def test(node): 307 if not (isinstance(node,BNode) or isinstance(node,URIRef)):314 if isinstance(node, Literal): 308 315 return False 309 316 for s,p,o in db.triples((None,None,node)): … … 312 319 else: 313 320 raise AttributeError, "unknown cascade argument" 314 for s,p,o in db.triples((node , None, None)):321 for s,p,o in db.triples((noderef, None, None)): 315 322 db.remove((s,p,o)) 316 323 if test(o): 317 self._remove(node=o, db=db,cascade=cascade) 324 rdfSubject(o)._remove(db=db,cascade=cascade) 325 318 326 319 327 def _rename(self, name, db=None): … … 321 329 if not db: 322 330 db = self.db 323 if not (isinstance(name, BNode) or isinstance(name,URIRef)):331 if not (isinstance(name, (BNode,URIRef))): 324 332 raise AttributeError, ("cannot rename to %s" % name) 325 for s,p,o in db.triples((self ,None,None)):333 for s,p,o in db.triples((self.resUri,None,None)): 326 334 db.set((name, p, o)) 327 for s,p,o in db.triples((None,None,self )):335 for s,p,o in db.triples((None,None,self.resUri)): 328 336 db.set((s, p, name)) 329 337 self.resUri = name … … 335 343 returning all predicate object pairs with qnames""" 336 344 db = db or self.db 337 for p,o in db.predicate_objects(self ):345 for p,o in db.predicate_objects(self.resUri): 338 346 print "%20s = %s"% (db.qname(p),str(o)) 339 347 print " " -
rdfalchemy/trunk/rdfalchemy/samples/example.py
r91 r94 9 9 10 10 class Company(rdfSubject): 11 owlType = OV.Company11 rdf_type = OV.Company 12 12 symbol = rdflibSingle(OV.symbol,'symbol') 13 13 cik = rdflibSingle(OV.secCik,'cik') -
rdfalchemy/trunk/rdfalchemy/sesame2.py
r92 r94 31 31 """openrdf-sesame graph via http 32 32 Uses the sesame2 HTTP communication protocol 33 to provide rdflib type api 34 constructor takes http endpoint and repository name 35 e.g. 36 SesameGraph('http://www.openvest.org:8080/sesame/repositories/Test')""" 33 to provide rdflib type api constructor takes http endpoint and repository name 34 e.g. SesameGraph('http://www.openvest.org:8080/sesame/repositories/Test')""" 37 35 38 36 def __init__(self, url, context=None): … … 163 161 164 162 def parse(self, source, publicID=None, format="xml", method='POST'): 165 """ Parse source into Graph 163 """ 164 Parse source into Graph 166 165 167 166 Graph will get loaded into it's own context (sub graph). 168 167 Format defaults to xml (AKA rdf/xml). 169 The publicID argument is for specifying the logical URI 170 for the case that it's different from the physical source URI. 171 Returns the context into which the source was parsed. 172 POST method adds data in a context 173 PUT method replaces data in a context 168 169 :param publicID: *optional* the logical URI if it's different from the physical source URI. 170 :returns: Returns the context into which the source was parsed. 171 :param method: must be one of 172 173 'POST' -- method adds data to a context 174 'PUT' -- method replaces data in a context 174 175 """ 175 176 url = self.url+'/statements' -
rdfalchemy/trunk/rdfalchemy/sparql.py
r71 r94 28 28 gives 'read-only' access to the graph 29 29 constructor takes http endpoint and repository name 30 e.g. 31 SPARQLGraph('http://localhost:2020/sparql')""" 30 e.g. SPARQLGraph('http://localhost:2020/sparql')""" 32 31 33 32 def __init__(self, url, context=None): … … 39 38 Executes a SPARQL Construct 40 39 strOrTriple - can be either: 41 a string in which case it it considered a CONSTRUCT query 42 a triple in which case it acts as the rdflib `triples((s,p,o))` 40 41 * a string in which case it it considered a CONSTRUCT query 42 * a triple in which case it acts as the rdflib `triples((s,p,o))` 43 43 44 initBindings - A mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query) 44 45 initNS - A mapping from a namespace prefix to a namespace … … 66 67 67 68 def triples(self, (s,p,o), method='CONSTRUCT'): 68 """returns a generator over triples matching the pattern 69 method must be 'CONSTRUCT' or 'SELECT' 70 CONSTRUCT calls CONSTRUCT query and returns a Graph result 71 SELECT calls a SELECT query and returns an interator streaming over the results 69 """ 70 :returns: a generator over triples matching the pattern 71 :param method: must be 'CONSTRUCT' or 'SELECT' 72 73 * CONSTRUCT calls CONSTRUCT query and returns a Graph result 74 * SELECT calls a SELECT query and returns an interator streaming over the results 75 72 76 Use SELECT if you expect a large result set or may consume less than the entire result""" 73 77 if method == 'CONSTRUCT': … … 124 128 125 129 126 def value(self, subject=None, predicate=RDF.value, object=None, 127 default=None, any=True): 130 def value(self, subject=None, predicate=RDF.value, object=None, default=None, any=True): 128 131 """Get a value for a pair of two criteria 129 132 … … 131 134 knows that there may only be one value. 132 135 133 It is one of those situations that occur a lot, hence this 134 'macro' like utility 135 136 Parameters: 137 ----------- 138 subject, predicate, object -- exactly one must be None 139 default -- value to be returned if no values found 140 any -- if True: 141 return any value in the case there is more than one 142 else: 143 raise UniquenessError 136 It is one of those situations that occur a lot, hence this *macro* like utility 137 138 :param subject, predicate, object: exactly one must be None 139 :param default: value to be returned if no values found 140 :param any: if more than one answer return **any one** answer, otherwise `raise UniquenessError` 144 141 """ 145 142 retval = default … … 217 214 """ 218 215 Executes a SPARQL query against this Graph 219 strOrQuery - Is either a string consisting of the SPARQL query 220 initBindings - optional mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query) 221 initNS - optional mapping from a namespace prefix to a namespace 222 resultMethod - results query requested (must be 'xml' or 'json') 223 xml streams over the result set and json must read the entire set to succeed 224 processor - The kind of RDF query (must be 'sparql' or 'serql') 216 217 :param strOrQuery: Is either a string consisting of the SPARQL query 218 :param initBindings: *optional* mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query) 219 :param initNs: optional mapping from a namespace prefix to a namespace 220 :param resultMethod: results query requested (must be 'xml' or 'json') 221 xml streams over the result set and json must read the entire set to succeed 222 :param processor: The kind of RDF query (must be 'sparql' or 'serql') 225 223 """ 226 224 query = strOrQuery … … 305 303 """ 306 304 Executes a SPARQL describe of resource 307 s_or_po is either: 305 306 :param s_or_po: is either 308 307 309 308 * a subject ... should be a URIRef … … 311 310 * a describe query string 312 311 313 initBindings -A mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query)314 initNS -A mapping from a namespace prefix to a namespace312 :param initBindings: A mapping from a Variable to an RDFLib term (used as initial bindings for SPARQL query) 313 :param initNs: A mapping from a namespace prefix to a namespace 315 314 """ 316 315 if isinstance(s_or_po, str): -
rdfalchemy/trunk/setup.py
r61 r94 17 17 packages=find_packages(exclude=['ez_setup']), 18 18 include_package_data=True, 19 platforms = ["any"], 20 classifiers = ["Programming Language :: Python", 21 "License :: OSI Approved :: BSD License", 22 "Topic :: Software Development :: Libraries :: Python Modules", 23 "Operating System :: OS Independent", 24 "Natural Language :: English", 25 ], 26 19 27 )
