python-odata icon indicating copy to clipboard operation
python-odata copied to clipboard

Handle metadata_url separately

Open attieretief opened this issue 4 years ago • 6 comments

Using this library to consume Microsoft Dynamics 365 Business Central (formerly Microsoft Dynamics NAV) ODataV4 web services, I had to find a way to not be limited to the default service company of the endpoint.

Normally, to specify a company within the source database to connect to, the url would be in the form of <endpoint>/Company('CompanyName')/EntitySet

But providing this as url to the ODataService class does not accept $metadata

The solution is to pass <endpoint>/Company('CompanyName')/ as url to ODataService and pass <endpoint>/ as new metadata_url parameter to ODataService

image

And then additionaly, in the Metadata class, use the metadata_url instead of url

image

Happy to contribute the code changes if required

LOVE this library

attieretief avatar Mar 27 '20 19:03 attieretief

Hi @attieretief. I am not following what you are getting at here.

It looks to me like is what you should be using for the URL (and therefore metadata url).

Is it that Microsoft Dynamics 365 Business Central has company-specific entities? In other words you can only get the entities you want when you include the Company('CompanyName') in the url? Or is it possible to get to them through the company?

tpow avatar Jul 08 '20 17:07 tpow

@tpow it's the former...you have to specify the company in the URL

attieretief avatar Jul 08 '20 17:07 attieretief

@attieretief Are you trying to use python-odata with reflect_entities=True or have you built your own models? What does it do if you do not specify the company? Not connect? Not return entities?

tpow avatar Jul 08 '20 17:07 tpow

@tpow I you don't specify the company the MSDYN365BC service returns data for the company specified in the default company parameter of the BC service. This is obviously limited if you want to retrieve data from multiple companies in a single database. If you DO specify the company in he URL, the library dis not resolve the metadata properly. This is why I split the service URL and the metadata URL, which solces the problem. I'm using it successfully in a production environment.

attieretief avatar Jul 08 '20 17:07 attieretief

@attieretief This sounds to me like a library defect. I believe that every OData 4 query is supposed to return the "@odata.context". (Perhaps this is provided if the query includes $format=application/json;odata.metadata=full) The "@odata.context" should include the correct reference to the entity in the metadata url. If it is working as described in your example, it would reference /$metadata#EntityName and would not include the company name. However, I believe the python-odata library tries to retrieve all of this information beforehand when using reflect_entities and never looks at the context.

Your solution sounds easy enough. Do you then use multiple service connections for the various companies?

tpow avatar Jul 08 '20 18:07 tpow

Yes I do

attieretief avatar Jul 08 '20 18:07 attieretief