tuomur / python-odata

A simple library for read/write access to OData services
MIT License
79 stars 59 forks source link

Add Singleton Support #15

Open therealmitchconnors opened 6 years ago

therealmitchconnors commented 6 years ago

Implement QuerySingle methods and classes to support singleton operations.

therealmitchconnors commented 6 years ago

Fixes #14

tuomur commented 6 years ago

Thanks for looking into this. Copying all of query.py just for some small changes seems a bit too excessive. You could likely implement this in a more leaner way with a Entity subclass that returns the singleton's URL when queried. Metadata also would need to properly construct the Singleton classes.

therealmitchconnors commented 6 years ago

I have trimmed out all the functions that were not used by singletons (filter, top, skip, etc). I see that I could trim a bit more from the get_options and new_query functions where they relate to those operators to reduce the size of this feature, but I think the rest of the class is being used...

With regard to the Entity subclass, what would that look like? With reference to the TripPin service, we would construct the Person entity, as well as a PersonSingle sublcass? How would we execute the query? Would the query return a Person entity or a PersonSingle entity?

Thanks!

tuomur commented 6 years ago

I had a look at Singletons too, and ended up rewriting some of the EntitySet handling. Check it out at 9bfff032c54c3356e102487e33d40f879cb8172f (new branch)

I tested this with the TripPin URL you mentioned.

therealmitchconnors commented 6 years ago

That looks promising. How would you go about using this model from the Service class? Something like service.query(Customer, 'CustomerSingleton')?

tuomur commented 6 years ago

Sorry, forgot to mention the usage changes :)

Service.entities now contains the EntitySets with their original names (People, NewComePeople, Me) and those classes can be queried as usual. So for example:

Service = ODataService('http://services.odata.org/TripPinRESTierService/', reflect_entities=True)
Me = Service.entities['Me']
me = Service.query(Me).first()
therealmitchconnors commented 6 years ago

I see, so singletons are effectively just an array of one?

tuomur commented 6 years ago

I merged my singleton branch to master.

tpow commented 5 years ago

This pull request can be closed. @tuomur implemented singleton support and merged it to master.