{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Conect to Odoo database" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we connect to odoo database via XML RPC protocol.\n", "For all possible arguments of Client class look at [documentation](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.html#openerp_proxy.core.Client)" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true }, "outputs": [], "source": [ "# Import Client and Session classes\n", "from openerp_proxy import (Client,\n", " Session)\n", "\n", "cl = Client('localhost', 'openerp_proxy_test_db', 'admin', 'admin', protocol='xml-rpc')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also it is posible to use JSON-RPC protocol, and HTTPS versions of both XML-RPC and JSON-RPC.\n", "Note that connection via HTTPS is not well tested, but if there are some errors, while connection, just fill an issue on github project page." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To list all available connectors, use [openerp_proxy.connection.get_connector_names()](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.connection.html#openerp_proxy.connection.connection.get_connector_names) which returns a list with registered connector names.\n", "\n", "By default they are:\n", "- *xml-rpc*\n", "- *xml-rpcs*\n", "- *json-rpc*\n", "- *json-rpcs*." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['json-rpc', 'xml-rpc', 'xml-rpcs', 'json-rpcs']" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from openerp_proxy.connection import get_connector_names\n", "get_connector_names()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But new connectors could be easily added via extension mechanism. For examples look at source code of ```openerp_proxy.connection``` package." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Client usage" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Client instance is a start point of any usage of this project.\n", "For low level code, it provides [execute](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.html#openerp_proxy.core.Client.execute) method which allows to execute any public method on any model of connected Odoo instance and [execute_wkf](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.html#openerp_proxy.core.Client.execute_wkf) method, which sends signal to workflow engine:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So simple search-read code should look like:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[{'country_id': [21, 'Belgium'], 'id': 31, 'name': 'Michel Fletcher'},\n", " {'country_id': [21, 'Belgium'], 'id': 30, 'name': 'Thomas Passot'},\n", " {'country_id': [229, 'Taiwan'], 'id': 29, 'name': 'Joseph Walters'}]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "partner_ids = cl.execute('res.partner', 'search', [('parent_id', '!=', False)], limit=3)\n", "partner_data = cl.execute('res.partner', 'read', partner_ids, ['id', 'name', 'country_id'])\n", "partner_data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# ORM functionality" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But to simplify code of data processing there are ORM layer, which usualy accesed from Client instances." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Few notes about terminology:\n", "- Term 'object' here and in documentation mostly refers to Odoo's Model (Document type)\n", "- Term 'record' here and in documentation mostly refers to single Odoo's document (database record)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next code demonstrate's [client.get_obj()](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.html#openerp_proxy.core.Client.get_obj), [object.search()]() and [object.read()]() methods.\n", "at first we get partner object, then search for partners that have parent partners, and finaly we read 3 fields for each partner searched.\n", "\n", "```search``` and ```read``` are standard Odoo methods, and all arguments will be passed directly to server" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[{'country_id': [21, 'Belgium'], 'id': 31, 'name': 'Michel Fletcher'},\n", " {'country_id': [21, 'Belgium'], 'id': 30, 'name': 'Thomas Passot'},\n", " {'country_id': [229, 'Taiwan'], 'id': 29, 'name': 'Joseph Walters'}]" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "partner_obj = cl.get_obj('res.partner')\n", "partner_ids = partner_obj.search([('parent_id', '!=', False)], limit=3)\n", "partner_data = partner_obj.read(partner_ids, ['id', 'name', 'country_id'])\n", "partner_data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This code looks much simpler! But if dealing with relational fields, is still not so comfortable as desired. For example, we want to get list of country codes, of partners selected. Our code will be something similar to:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['BE', 'TW']" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "country_ids = [p['country_id'][0] for p in partner_data]\n", "country_data = cl['res.country'].read(country_ids, ['code'])\n", "country_codes = [c['code'] for c in country_data]\n", "country_codes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But there are simpler way to do this, using special methods [search_records](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.orm.html#openerp_proxy.orm.record.ObjectRecords.search_records) and [read_records](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.orm.html#openerp_proxy.orm.record.ObjectRecords.read_records), that wraps data been read in [RecordList](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.orm.html#openerp_proxy.orm.record.RecordList) or [Record](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.orm.html#openerp_proxy.orm.record.Record) classes.\n", "\n", "Note that, while ```search_records``` method usualy returns ```RecordList``` instance, ```read_records``` will return single ```Record``` instance if single ```id``` is passed to it instead of list of ids." ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['BE', 'TW']" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "partner_obj = cl['res.partner']\n", "partners = partner_obj.search_records([('parent_id','!=', False)], limit=3)\n", "country_codes = [p.country_id.code for p in partners]\n", "\n", "# and to remove dublicates\n", "country_codes = list(set(country_codes))\n", "country_codes" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Also there is [RecordList.mapped](http://pythonhosted.org/openerp_proxy/module_ref/openerp_proxy.orm.html#openerp_proxy.orm.record.RecordList.mapped) method, that could help a lot. It mostly same as serverside [RecordSet.mapped](http://doc.openstone.cn/9.0/reference/orm.html#openerp.models.Model.mapped) method, but does not support function as parametr yet.\n", "Code which uses it may look like:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "['BE', 'TW']" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "partner_obj = cl['res.partner']\n", "partners = partner_obj.search_records([('parent_id','!=', False)], limit=3)\n", "country_codes = partners.mapped('country_id.code')\n", "country_codes" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.12+" } }, "nbformat": 4, "nbformat_minor": 0 }