sparta & my ideal python/rdf api
I've been using sparta quite a bit recently, and have found it to be a really cool way of handling rdf in python. For me it's about 80% there.
The main problem is that fundamentally there's a mismatch between the way python represents objects and rdf constrains resources: In python, an object has at most 1 value for each property. In RDF a resource can have multiple values of the same property (corresponding to multiple subject,property,value statements).
Sparta currently handles this mismatch by using a generator interface for each property allowing you to get each value by doing:
for value in myresource.property:
# .. do something with value
This is great for properties that do have multiple values, but I find that most properties in my data don't follow this rule and I have a lot of:
a = myresource.property.next()
lines littering my code. Also when setting values on a resource I have to delete the original value before setting it (in order to overwrite it).
del(myresource.property) myresource.property = "newvalue"
Sparta does support a feature that if there exists a statement setting the 'owl:maxCardinality' of a property is '1', it treats the property as a pythonic attribute, allowing you to do
myresource.property = "newvalue" # overwrites the old value print myresource.property # prints "myvalue"
Unfortunately I can see 2 problems with this feature:
- Using it requires you to effectively declare your properties before use (which inhibits my python coding habits)
- The addition of an owl:maxCardinality statement can cause existing code to break
Instead, I was wondering if the maxCardinality=1 behaviour could be the default. Something like the following:
.
print resource.property # get the value of 'property'. If there are
# multiple values then arbitrarily pick one
# (or maybe raise an exception)
.
for value in resource.property: # iterate over all values of 'property'
print value
.
resource.property = "foo" # remove any existing 'property' values
# and assert "foo"
.
resource.add('property',value) # add an additional property/value statement
# for resource
Seems quite natural and doable to me - can anybody see any problems with this?