Connector

class connector.connector.Binder(connector_env)[source]

Bases: connector.connector.ConnectorUnit

For one record of a model, capable to find an external or internal id, or create the binding (link) between them

This is a default implementation that can be inherited or reimplemented in the connectors.

This implementation assumes that binding models are _inherits of the models they are binding.

bind(external_id, binding_id)[source]

Create the link between an external ID and an OpenERP ID

Parameters:
  • external_id – external id to bind
  • binding_id (int) – OpenERP ID to bind
to_backend(binding_id, wrap=False)[source]

Give the external ID for an OpenERP binding ID

Parameters:
  • binding_id – OpenERP binding ID for which we want the backend id
  • wrap – if False, binding_id is the ID of the binding, if True, binding_id is the ID of the normal record, the method will search the corresponding binding and returns the backend id of the binding
Returns:

external ID of the record

to_openerp(external_id, unwrap=False)[source]

Give the OpenERP ID for an external ID

Parameters:
  • external_id – external ID for which we want the OpenERP ID
  • unwrap – if True, returns the normal record else return the binding record
Returns:

a recordset, depending on the value of unwrap, or an empty recordset if the external_id is not mapped

Return type:

recordset

unwrap_binding(binding_id, browse=False)[source]

For a binding record, gives the normal record.

Example: when called with a magento.product.product id, it will return the corresponding product.product id.

Parameters:browse – when True, returns a browse_record instance rather than an ID
unwrap_model()[source]

For a binding model, gives the normal model.

Example: when called on a binder for magento.product.product, it will return product.product.

class connector.connector.ConnectorEnvironment(backend_record, session, model_name)[source]

Bases: object

Environment used by the different units for the synchronization.

backend

Current backend we are working with. Obtained with backend_record.get_backend().

Instance of: connector.backend.Backend

backend_record

Browsable record of the backend. The backend is inherited from the model connector.backend and have at least a type and a version.

session

Current session we are working in. It contains the OpenERP cr, uid and context.

model_name

Name of the OpenERP model to work with.

_propagate_kwargs

List of attributes that must be used by connector.connector.ConnectorEnvironment.create_environment() when a new connector environment is instantiated.

classmethod create_environment(backend_record, session, model, connector_env=None)[source]

Create a new environment ConnectorEnvironment.

Parameters:
env
get_connector_unit(base_class)[source]

Searches and returns an instance of the ConnectorUnit for the current model and being a class or subclass of base_class.

The returned instance is built with self for its environment.

Parameters:base_class (connector.connector.ConnectorUnit) – ConnectorUnit to search (class or subclass)
model
pool
set_lang(*args, **kwds)[source]

Change the working language in the environment.

It changes the lang key in the session’s context.

class connector.connector.ConnectorUnit(connector_env)[source]

Bases: object

Abstract class for each piece of the connector:

Examples:

Or basically any class intended to be registered in a Backend.

advisory_lock_or_retry(lock, retry_seconds=1)[source]

Acquire a Postgres transactional advisory lock or retry job

When the lock cannot be acquired, it raises a RetryableJobError so the job is retried after n retry_seconds.

Usage example:

lock_name = 'import_record({}, {}, {}, {})'.format(
    self.backend_record._name,
    self.backend_record.id,
    self.model._name,
    self.external_id,
)
self.advisory_lock_or_retry(lock_name, retry_seconds=2)

See :func:openerp.addons.connector.connector.pg_try_advisory_lock for details.

Parameters:
  • lock – The lock name. Can be anything convertible to a string. It needs to represent what should not be synchronized concurrently, usually the string will contain at least: the action, the backend type, the backend id, the model name, the external id
  • retry_seconds – number of seconds after which a job should be retried when the lock cannot be acquired.
binder_for(model=None)[source]

Returns an new instance of the correct Binder for a model

env

Returns the openerp.api.environment

environment
get_binder_for_model(model=None)[source]

Returns an new instance of the correct Binder for a model

Deprecated, use binder_for now.

get_connector_unit_for_model(connector_unit_class, model=None)[source]

Deprecated in favor of unit_for()

localcontext

It is there for compatibility.

openerp.tools.translate._() searches for this attribute in the classes do be able to translate the strings.

There is no reason to use this attribute for other purposes.

classmethod match(session, model)[source]

Returns True if the current class correspond to the searched model.

Parameters:
model
unit_for(connector_unit_class, model=None)[source]

According to the current ConnectorEnvironment, search and returns an instance of the ConnectorUnit for the current model and being a class or subclass of connector_unit_class.

If a different model is given, a new ConnectorEnvironment is built for this model. The class used for creating the new environment is the same class as in self.connector_env which must be ConnectorEnvironment or a subclass.

Parameters:
  • connector_unit_class (connector.                                               connector.ConnectorUnit) – ConnectorUnit to search (class or subclass)
  • model (str) – to give if the ConnectorUnit is for another model than the current one
class connector.connector.MetaConnectorUnit(name, bases, attrs)[source]

Bases: type

Metaclass for ConnectorUnit.

Keeps a _module attribute on the classes, the same way OpenERP does it for the Model classes. It is then used to filter them according to the state of the module (installed or not).

for_model_names

Returns the list of models on which a ConnectorUnit is usable

It is used in match() when we search the correct ConnectorUnit for a model.

model_name
connector.connector.get_openerp_module(cls_or_func)[source]

For a top level function or class, returns the name of the OpenERP module where it lives.

So we will be able to filter them according to the modules installation state.

connector.connector.install_in_connector()[source]
connector.connector.is_module_installed(env, module_name)[source]

Check if an Odoo addon is installed.

Parameters:module_name – name of the addon
connector.connector.pg_try_advisory_lock(env, lock)[source]

Try to acquire a Postgres transactional advisory lock.

The function tries to acquire a lock, returns a boolean indicating if it could be obtained or not. An acquired lock is released at the end of the transaction.

A typical use is to acquire a lock at the beginning of an importer to prevent 2 jobs to do the same import at the same time. Since the record doesn’t exist yet, we can’t put a lock on a record, so we put an advisory lock.

Example:
  • Job 1 imports Partner A
  • Job 2 imports Partner B
  • Partner A has a category X which happens not to exist yet
  • Partner B has a category X which happens not to exist yet
  • Job 1 import category X as a dependency
  • Job 2 import category X as a dependency

Since both jobs are executed concurrently, they both create a record for category X so we have duplicated records. With this lock:

  • Job 1 imports Partner A, it acquires a lock for this partner
  • Job 2 imports Partner B, it acquires a lock for this partner
  • Partner A has a category X which happens not to exist yet
  • Partner B has a category X which happens not to exist yet
  • Job 1 import category X as a dependency, it acquires a lock for this category
  • Job 2 import category X as a dependency, try to acquire a lock but can’t, Job 2 is retried later, and when it is retried, it sees the category X created by Job 1.

The lock is acquired until the end of the transaction.

Usage example:

lock_name = 'import_record({}, {}, {}, {})'.format(
    self.backend_record._name,
    self.backend_record.id,
    self.model._name,
    self.external_id,
)
if pg_try_advisory_lock(lock_name):
    # do sync
else:
    raise RetryableJobError('Could not acquire advisory lock',
                            seconds=2,
                            ignore_retry=True)
Parameters:
  • env – the Odoo Environment
  • lock – The lock name. Can be anything convertible to a string. It needs to represents what should not be synchronized concurrently so usually the string will contain at least: the action, the backend type, the backend id, the model name, the external id

:return True/False whether lock was acquired.