Skip to content

Commit

Permalink
Merge pull request #80 from hbrunn/master-load_data-update
Browse files Browse the repository at this point in the history
[ADD] support update mode where we never try to create records
  • Loading branch information
StefanRijnhart authored Oct 6, 2017
2 parents a0e70c9 + 522665b commit 6b3d130
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
50 changes: 47 additions & 3 deletions openupgradelib/openupgrade.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
import inspect
import uuid
import logging
try:
from StringIO import StringIO
except ImportError:
from io import StringIO
from contextlib import contextmanager
try:
from contextlib import ExitStack
Expand All @@ -46,6 +50,7 @@ def __exit__(self, exc_type, exc_value, traceback):
self._cms.pop().__exit__(exc_type, exc_value, traceback)

from psycopg2.extensions import AsIs
from lxml import etree
from . import openupgrade_tools

core = None
Expand Down Expand Up @@ -249,9 +254,14 @@ def load_data(cr, module_name, filename, idref=None, mode='init'):
:param filename: the path to the filename, relative to the module \
directory.
:param idref: optional hash with ?id mapping cache?
:param mode: one of 'init', 'update', 'demo'. Always use 'init' \
for adding new items from files that are marked with 'noupdate'. Defaults \
to 'init'.
:param mode: one of 'init', 'update', 'demo', 'init_no_create'. \
Always use 'init' for adding new items from files that are marked with \
'noupdate'. Defaults to 'init'.
'init_no_create' is a hack to load data for records which have \
forcecreate=False set. As those records won't be recreated during the \
update, standard Odoo would recreate the record if it was deleted, \
but this will fail in cases where there are required fields to be \
filled which are not contained in the data file.
"""

if idref is None:
Expand All @@ -267,11 +277,45 @@ def load_data(cr, module_name, filename, idref=None, mode='init'):
cr, module_name, pathname, fp.read(), idref, mode, noupdate)
elif ext == '.yml':
yaml_import(cr, module_name, fp, None, idref=idref, mode=mode)
elif mode == 'init_no_create':
for fp2 in _get_existing_records(cr, fp, module_name):
tools.convert_xml_import(
cr, module_name, fp2, idref, mode='init',
)
else:
tools.convert_xml_import(cr, module_name, fp, idref, mode=mode)
finally:
fp.close()

def _get_existing_records(cr, fp, module_name):
"""yield file like objects per 'leaf' node in the xml file that exists.
This is for not trying to create a record with partial data in case the
record was removed in the database."""
def yield_element(node, path=None):
if node.tag not in ['openerp', 'odoo', 'data']:
if node.tag == 'record':
xmlid = node.attrib['id']
if '.' not in xmlid:
module = module_name
else:
module, xmlid = xmlid.split('.', 1)
cr.execute(
'select id from ir_model_data where module=%s and name=%s',
(module, xmlid)
)
if not cr.rowcount:
return
yield StringIO(etree.tostring(path))
else:
for child in node:
for value in yield_element(
child,
etree.SubElement(path, node.tag, node.attrib)
if path else etree.Element(node.tag, node.attrib)
):
yield value
return yield_element(etree.parse(fp).getroot())

# for backwards compatibility
load_xml = load_data
table_exists = openupgrade_tools.table_exists
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ coveralls
# Version locked due to https://gitlab.com/pycqa/flake8/issues/268
flake8==3.2.0
pep8-naming
lxml

0 comments on commit 6b3d130

Please sign in to comment.