credativ team mailing list archive
-
credativ team
-
Mailing list archive
-
Message #05922
[Merge] lp:~therp-nl/openupgrade-server/8.0-openupgrade_core_style into lp:openupgrade-server/8.0
Stefan Rijnhart (Therp) has proposed merging lp:~therp-nl/openupgrade-server/8.0-openupgrade_core_style into lp:openupgrade-server/8.0.
Requested reviews:
OpenUpgrade Committers (openupgrade-committers)
For more details, see:
https://code.launchpad.net/~therp-nl/openupgrade-server/8.0-openupgrade_core_style/+merge/218285
Style: flake8
Keep deferred hook as deferred_80
Keep 7.0 specific API for autodoc
--
https://code.launchpad.net/~therp-nl/openupgrade-server/8.0-openupgrade_core_style/+merge/218285
Your team OpenUpgrade Committers is requested to review the proposed merge of lp:~therp-nl/openupgrade-server/8.0-openupgrade_core_style into lp:openupgrade-server/8.0.
=== modified file 'openerp/modules/loading.py'
--- openerp/modules/loading.py 2014-04-08 11:08:01 +0000
+++ openerp/modules/loading.py 2014-05-05 13:52:55 +0000
@@ -43,7 +43,7 @@
from openerp.modules.module import initialize_sys_path, \
load_openerp_module, init_module_models, adapt_version
-from openerp.openupgrade import openupgrade_loading
+from openerp.openupgrade import openupgrade_loading, deferred_80
_logger = logging.getLogger(__name__)
_test_logger = logging.getLogger('openerp.tests')
@@ -394,6 +394,10 @@
# Cleanup orphan records
registry['ir.model.data']._process_end(cr, SUPERUSER_ID, processed_modules)
+ # OpenUpgrade: call deferred migration steps
+ if update_module:
+ deferred_80.migrate_deferred(cr, pool)
+
for kind in ('init', 'demo', 'update'):
tools.config[kind] = {}
=== added file 'openerp/openupgrade/deferred_80.py'
--- openerp/openupgrade/deferred_80.py 1970-01-01 00:00:00 +0000
+++ openerp/openupgrade/deferred_80.py 2014-05-05 13:52:55 +0000
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2014 Therp BV (<http://therp.nl>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+"""
+This module can be used to contain functions that should be called at the end
+of the migration. A migration may be run several times after corrections in
+the code or the configuration, and there is no way for OpenERP to detect a
+succesful result. Therefore, the functions in this module should be robust
+against being run multiple times on the same database.
+"""
+
+
+def migrate_deferred(cr, pool):
+ pass
=== modified file 'openerp/openupgrade/doc/source/conf.py'
--- openerp/openupgrade/doc/source/conf.py 2014-05-01 10:22:29 +0000
+++ openerp/openupgrade/doc/source/conf.py 2014-05-05 13:52:55 +0000
@@ -4,15 +4,18 @@
# OpenUpgrade documentation build configuration file, created by
# sphinx-quickstart on Wed Nov 30 10:38:00 2011.
#
-# This file is execfile()d with the current directory set to its containing dir.
+# This file is execfile()d with the current directory set to its containing
+# dir.
#
# The contents of this file are pickled, so don't put values in the namespace
-# that aren't pickleable (module imports are okay, they're removed automatically).
+# that aren't pickleable (module imports are okay, they're removed
+# automatically).
#
# All configuration values have a default value; values that are commented out
# serve to show the default value.
-import sys, os
+import sys
+import os
# If your extensions are in another directory, add it here. If the directory
# is relative to the documentation root, use os.path.abspath to make it
@@ -22,7 +25,8 @@
# General configuration
# ---------------------
-# Add any Sphinx extension module names here, as strings. They can be extensions
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc']
@@ -56,11 +60,12 @@
# List of documents that shouldn't be included in the build.
#unused_docs = []
-# List of directories, relative to source directories, that shouldn't be searched
-# for source files.
+# List of directories, relative to source directories, that shouldn't be
+# searched for source files.
#exclude_dirs = []
-# The reST default role (used for this markup: `text`) to use for all documents.
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
#default_role = None
# If true, '()' will be appended to :func: etc. cross-reference text.
@@ -156,10 +161,11 @@
#latex_font_size = '10pt'
# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, document class [howto/manual]).
+# (source start file, target name, title, author, document class
+# [howto/manual]).
latex_documents = [
- ('index', 'OpenUpgrade.tex', 'OpenUpgrade Documentation',
- 'The OpenUpgrade team', 'manual'),
+ ('index', 'OpenUpgrade.tex', 'OpenUpgrade Documentation',
+ 'The OpenUpgrade team', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -179,6 +185,7 @@
# If false, no module index is generated.
#latex_use_modindex = True
+
# Use Mock classes for building on readthedocs.org
# http://read-the-docs.readthedocs.org/en/latest/faq.html
class Mock(object):
@@ -200,4 +207,3 @@
MOCK_MODULES = ['osv', 'pooler', 'tools']
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = Mock()
-
=== modified file 'openerp/openupgrade/openupgrade.py'
--- openerp/openupgrade/openupgrade.py 2014-04-08 11:08:01 +0000
+++ openerp/openupgrade/openupgrade.py 2014-05-05 13:52:55 +0000
@@ -22,7 +22,7 @@
import os
import inspect
import logging
-from openerp import release, osv, pooler, tools, SUPERUSER_ID
+from openerp import release, orm, tools, SUPERUSER_ID
import openupgrade_tools
# The server log level has not been set at this point
@@ -51,17 +51,19 @@
'get_legacy_name',
'm2o_to_m2m',
'message',
-]
+]
+
def load_data(cr, module_name, filename, idref=None, mode='init'):
"""
- Load an xml or csv data file from your post script. The usual case for this is the
+ Load an xml or csv data file from your post script. The usual case for
+ this is the
occurrence of newly added essential or useful data in the module that is
marked with "noupdate='1'" and without "forcecreate='1'" so that it will
- not be loaded by the usual upgrade mechanism. Leaving the 'mode' argument to
- its default 'init' will load the data from your migration script.
-
- Theoretically, you could simply load a stock file from the module, but be
+ not be loaded by the usual upgrade mechanism. Leaving the 'mode' argument
+ to its default 'init' will load the data from your migration script.
+
+ Theoretically, you could simply load a stock file from the module, but be
careful not to reinitialize any data that could have been customized.
Preferably, select only the newly added items. Copy these to a file
in your migrations directory and load that file.
@@ -74,9 +76,9 @@
: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'. Always use 'init' \
+ for adding new items from files that are marked with 'noupdate'. Defaults \
+ to 'init'.
"""
if idref is None:
@@ -88,7 +90,8 @@
try:
if ext == '.csv':
noupdate = True
- tools.convert_csv_import(cr, module_name, pathname, fp.read(), idref, mode, noupdate)
+ tools.convert_csv_import(
+ cr, module_name, pathname, fp.read(), idref, mode, noupdate)
else:
tools.convert_xml_import(cr, module_name, fp, idref, mode=mode)
finally:
@@ -98,23 +101,26 @@
load_xml = load_data
table_exists = openupgrade_tools.table_exists
+
def rename_columns(cr, column_spec):
"""
Rename table columns. Typically called in the pre script.
- :param column_spec: a hash with table keys, with lists of tuples as values. \
- Tuples consist of (old_name, new_name). Use None for new_name to trigger a \
- conversion of old_name using get_legacy_name()
+ :param column_spec: a hash with table keys, with lists of tuples as \
+ values. Tuples consist of (old_name, new_name). Use None for new_name \
+ to trigger a conversion of old_name using get_legacy_name()
"""
for table in column_spec.keys():
for (old, new) in column_spec[table]:
if new is None:
new = get_legacy_name(old)
logger.info("table %s, column %s: renaming to %s",
- table, old, new)
- cr.execute('ALTER TABLE "%s" RENAME "%s" TO "%s"' % (table, old, new,))
+ table, old, new)
+ cr.execute(
+ 'ALTER TABLE "%s" RENAME "%s" TO "%s"' % (table, old, new,))
cr.execute('DROP INDEX IF EXISTS "%s_%s_index"' % (table, old))
+
def rename_tables(cr, table_spec):
"""
Rename tables. Typically called in the pre script.
@@ -128,18 +134,19 @@
to_rename = [x[0] for x in table_spec]
for old, new in list(table_spec):
if (table_exists(cr, old + '_id_seq') and
- old + '_id_seq' not in to_rename):
+ old + '_id_seq' not in to_rename):
table_spec.append((old + '_id_seq', new + '_id_seq'))
for (old, new) in table_spec:
logger.info("table %s: renaming to %s",
old, new)
cr.execute('ALTER TABLE "%s" RENAME TO "%s"' % (old, new,))
+
def rename_models(cr, model_spec):
"""
Rename models. Typically called in the pre script.
:param model_spec: a list of tuples (old model name, new model name).
-
+
Use case: if a model changes name, but still implements equivalent
functionality you will want to update references in for instance
relation fields.
@@ -154,6 +161,7 @@
'WHERE relation = %s', (new, old,))
# TODO: signal where the model occurs in references to ir_model
+
def rename_xmlids(cr, xmlids_spec):
"""
Rename XML IDs. Typically called in the pre script.
@@ -164,13 +172,14 @@
for (old, new) in xmlids_spec:
if not old.split('.') or not new.split('.'):
logger.error(
- 'Cannot rename XMLID %s to %s: need the module '
- 'reference to be specified in the IDs' % (old, new))
+ 'Cannot rename XMLID %s to %s: need the module '
+ 'reference to be specified in the IDs' % (old, new))
else:
query = ("UPDATE ir_model_data SET module = %s, name = %s "
"WHERE module = %s and name = %s")
logged_query(cr, query, tuple(new.split('.') + old.split('.')))
+
def drop_columns(cr, column_spec):
"""
Drop columns but perform an additional check if a column exists.
@@ -184,14 +193,15 @@
logger.info("table %s: drop column %s",
table, column)
if column_exists(cr, table, column):
- cr.execute('ALTER TABLE "%s" DROP COLUMN "%s"' %
+ cr.execute('ALTER TABLE "%s" DROP COLUMN "%s"' %
(table, column))
else:
logger.warn("table %s: column %s did not exist",
- table, column)
+ table, column)
+
def delete_model_workflow(cr, model):
- """
+ """
Forcefully remove active workflows for obsolete models,
to prevent foreign key issues when the orm deletes the model.
"""
@@ -207,17 +217,18 @@
cr,
"DELETE FROM wkf WHERE osv = %s", (model,))
+
def warn_possible_dataloss(cr, pool, old_module, fields):
"""
- Use that function in the following case :
- if a field of a model was moved from a 'A' module to a 'B' module.
- ('B' depend on 'A'),
- This function will test if 'B' is installed.
+ Use that function in the following case:
+ if a field of a model was moved from a 'A' module to a 'B' module.
+ ('B' depend on 'A'),
+ This function will test if 'B' is installed.
If not, count the number of different value and possibly warn the user.
Use orm, so call from the post script.
-
+
:param old_module: name of the old module
- :param fields: list of dictionary with the following keys :
+ :param fields: list of dictionary with the following keys:
'table' : name of the table where the field is.
'field' : name of the field that are moving.
'new_module' : name of the new module
@@ -225,26 +236,27 @@
.. versionadded:: 7.0
"""
module_obj = pool.get('ir.module.module')
- for field in fields:
- module_ids = module_obj.search(cr, SUPERUSER_ID, [
+ for field in fields:
+ module_ids = module_obj.search(
+ cr, SUPERUSER_ID, [
('name', '=', field['new_module']),
('state', 'in', ['installed', 'to upgrade', 'to install'])
])
- if not module_ids:
+ if not module_ids:
cr.execute(
"SELECT count(*) FROM (SELECT %s from %s group by %s) "
"as tmp" % (
field['field'], field['table'], field['field']))
row = cr.fetchone()
- if row[0] == 1:
+ if row[0] == 1:
# not a problem, that field wasn't used.
# Just a loss of functionality
logger.info(
"Field '%s' from module '%s' was moved to module "
"'%s' which is not installed: "
"No dataloss detected, only loss of functionality"
- %(field['field'], old_module, field['new_module']))
- else:
+ % (field['field'], old_module, field['new_module']))
+ else:
# there is data loss after the migration.
message(
cr, old_module,
@@ -253,15 +265,16 @@
"There were %s distinct values in this field.",
field['field'], field['new_module'], row[0])
+
def set_defaults(cr, pool, default_spec, force=False):
"""
Set default value. Useful for fields that are newly required. Uses orm, so
call from the post script.
-
- :param default_spec: a hash with model names as keys. Values are lists of \
- tuples (field, value). None as a value has a special meaning: it assigns \
- the default value. If this value is provided by a function, the function is \
- called as the user that created the resource.
+
+ :param default_spec: a hash with model names as keys. Values are lists \
+ of tuples (field, value). None as a value has a special meaning: it \
+ assigns the default value. If this value is provided by a function, the \
+ function is called as the user that created the resource.
:param force: overwrite existing values. To be used for assigning a non- \
default value (presumably in the case of a new column). The ORM assigns \
the default value as declared in the model in an earlier stage of the \
@@ -271,8 +284,9 @@
"""
def write_value(ids, field, value):
- logger.debug("model %s, field %s: setting default value of resources %s to %s",
- model, field, ids, unicode(value))
+ logger.debug(
+ "model %s, field %s: setting default value of resources %s to %s",
+ model, field, ids, unicode(value))
for res_id in ids:
# Iterating over ids here as a workaround for lp:1131653
obj.write(cr, SUPERUSER_ID, [res_id], {field: value})
@@ -280,7 +294,9 @@
for model in default_spec.keys():
obj = pool.get(model)
if not obj:
- raise osv.except_osv("Migration: error setting default, no such model: %s" % model, "")
+ raise orm.except_orm(
+ "Error",
+ "Migration: error setting default, no such model: %s" % model)
for field, value in default_spec[model]:
domain = not force and [(field, '=', False)] or []
@@ -290,17 +306,17 @@
if value is None:
# Set the value by calling the _defaults of the object.
# Typically used for company_id on various models, and in that
- # case the result depends on the user associated with the object.
- # We retrieve create_uid for this purpose and need to call the _defaults
- # function per resource. Otherwise, write all resources at once.
+ # case the result depends on the user associated with the
+ # object. We retrieve create_uid for this purpose and need to
+ # call the defaults function per resource. Otherwise, write
+ # all resources at once.
if field in obj._defaults:
if not callable(obj._defaults[field]):
write_value(ids, field, obj._defaults[field])
else:
- # existence users is covered by foreign keys, so this is not needed
- # cr.execute("SELECT %s.id, res_users.id FROM %s LEFT OUTER JOIN res_users ON (%s.create_uid = res_users.id) WHERE %s.id IN %s" %
- # (obj._table, obj._table, obj._table, obj._table, tuple(ids),))
- cr.execute("SELECT id, COALESCE(create_uid, 1) FROM %s " % obj._table + "WHERE id in %s", (tuple(ids),))
+ cr.execute(
+ "SELECT id, COALESCE(create_uid, 1) FROM %s " %
+ obj._table + "WHERE id in %s", (tuple(ids),))
# Execute the function once per user_id
user_id_map = {}
for row in cr.fetchall():
@@ -310,26 +326,29 @@
user_id_map[user_id], field,
obj._defaults[field](obj, cr, user_id, None))
else:
- error = ("OpenUpgrade: error setting default, field %s with "
- "None default value not in %s' _defaults" % (
+ error = (
+ "OpenUpgrade: error setting default, field %s with "
+ "None default value not in %s' _defaults" % (
field, model))
logger.error(error)
# this exeption seems to get lost in a higher up try block
- osv.except_osv("OpenUpgrade", error)
+ orm.except_orm("OpenUpgrade", error)
else:
write_value(ids, field, value)
-
+
+
def logged_query(cr, query, args=None):
"""
Logs query and affected rows at level DEBUG
"""
if args is None:
args = []
- res = cr.execute(query, args)
+ cr.execute(query, args)
logger.debug('Running %s', query % tuple(args))
logger.debug('%s rows affected', cr.rowcount)
return cr.rowcount
+
def column_exists(cr, table, column):
""" Check whether a certain column exists """
cr.execute(
@@ -337,16 +356,17 @@
'WHERE attrelid = '
'( SELECT oid FROM pg_class WHERE relname = %s ) '
'AND attname = %s',
- (table, column));
+ (table, column))
return cr.fetchone()[0] == 1
+
def update_module_names(cr, namespec):
"""
Deal with changed module names of certified modules
in order to prevent 'certificate not unique' error,
as well as updating the module reference in the
XML id.
-
+
:param namespec: tuple of (old name, new name)
"""
for (old_name, new_name) in namespec:
@@ -360,6 +380,7 @@
"WHERE name = %s")
logged_query(cr, query, (new_name, old_name))
+
def add_ir_model_fields(cr, columnspec):
"""
Typically, new columns on ir_model_fields need to be added in a very
@@ -368,7 +389,7 @@
Do not use for fields with additional SQL constraints, such as a
reference to another table or the cascade constraint, but craft your
own statement taking them into account.
-
+
:param columnspec: tuple of (column name, column type)
"""
for column in columnspec:
@@ -376,6 +397,7 @@
column)
logged_query(cr, query, [])
+
def get_legacy_name(original_name):
"""
Returns a versioned name for legacy tables/columns/etc
@@ -388,6 +410,7 @@
return 'openupgrade_legacy_'+('_').join(
map(str, release.version_info[0:2]))+'_'+original_name
+
def m2o_to_m2m(cr, model, table, field, source_field):
"""
Recreate relations in many2many fields that were formerly
@@ -411,6 +434,7 @@
for row in cr.fetchall():
model.write(cr, SUPERUSER_ID, row[0], {field: [(4, row[1])]})
+
def message(cr, module, table, column,
message, *args, **kwargs):
"""
@@ -437,6 +461,7 @@
logger.warn(prefix + message, *argslist, **kwargs)
+
def migrate():
"""
This is the decorator for the migrate() function
@@ -448,7 +473,7 @@
"""
def wrap(func):
def wrapped_function(cr, version):
- stage = 'unknown'
+ stage = 'unknown'
module = 'unknown'
filename = 'unknown'
try:
@@ -471,7 +496,7 @@
func(cr, version)
except Exception, e:
logger.error(
- "%s: error in migration script %s: %s" %
+ "%s: error in migration script %s: %s" %
(module, filename, str(e).decode('utf8')))
logger.exception(e)
raise
=== added file 'openerp/openupgrade/openupgrade_70.py'
--- openerp/openupgrade/openupgrade_70.py 1970-01-01 00:00:00 +0000
+++ openerp/openupgrade/openupgrade_70.py 2014-05-05 13:52:55 +0000
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2013 Sylvain LE GAL
+# (C) 2013 Therp BV
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+# This module provides simple tools for openupgrade migration, specific for
+# the 6.1 -> 7.0 migration. It is kept in later editions to keep all the API
+# docs in the latest release.
+
+from openerp import SUPERUSER_ID
+
+
+def set_partner_id_from_partner_address_id(
+ cr, pool, model_name, partner_field, address_field, table=None):
+ """
+ Set the new partner_id on any table with migrated contact ids
+
+ :param model_name: the model name of the target table
+ :param partner_field: the column in the target model's table \
+ that will store the new partner when found
+ :param address_field: the legacy field in the model's table \
+ that contains the old address in the model's table
+ :param table: override the target model's table name in case it was renamed
+ :returns: nothing
+ """
+ model = pool.get(model_name)
+ table = table or model._table
+ # Cannot use cursor's string substitution for table names
+ cr.execute("""
+ SELECT target.id, address.openupgrade_7_migrated_to_partner_id
+ FROM %s as target,
+ res_partner_address as address
+ WHERE address.id = target.%s""" % (table, address_field))
+ for row in cr.fetchall():
+ model.write(cr, SUPERUSER_ID, row[0], {partner_field: row[1]})
+
+
+def get_partner_id_from_user_id(cr, user_id):
+ """
+ Get the new partner_id from user_id.
+ :param user_id : user previously used.
+ """
+ cr.execute("""
+ SELECT partner_id
+ FROM res_users
+ WHERE id=%s""", (user_id,))
+ return cr.fetchone()[0]
=== modified file 'openerp/openupgrade/openupgrade_loading.py'
--- openerp/openupgrade/openupgrade_loading.py 2014-04-08 11:08:01 +0000
+++ openerp/openupgrade/openupgrade_loading.py 2014-05-05 13:52:55 +0000
@@ -2,7 +2,7 @@
##############################################################################
#
# OpenERP, Open Source Management Solution
-# This module copyright (C) 2011-2012 Therp BV (<http://therp.nl>)
+# This module copyright (C) 2014 Therp BV (<http://therp.nl>)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -26,9 +26,10 @@
from openerp.openupgrade.openupgrade import table_exists
from openerp.tools import config, safe_eval
-# A collection of functions used in
+# A collection of functions used in
# openerp/modules/loading.py
+
def add_module_dependencies(cr, module_list):
"""
Select (new) dependencies from the modules in the list
@@ -47,12 +48,12 @@
forced_deps = safe_eval.safe_eval(
config.get_misc(
- 'openupgrade', 'forced_deps_' + release.version,
+ 'openupgrade', 'forced_deps_' + release.version,
config.get_misc('openupgrade', 'forced_deps', '{}')))
autoinstall = safe_eval.safe_eval(
config.get_misc(
- 'openupgrade', 'autoinstall_' + release.version,
+ 'openupgrade', 'autoinstall_' + release.version,
config.get_misc('openupgrade', 'autoinstall', '{}')))
for module in list(module_list):
@@ -69,9 +70,8 @@
AND ir_module_module.name in %s
""", (tuple(module_list),))
- return list(set(
- module_list + [x[0] for x in cr.fetchall()]
- ))
+ return list(set(module_list + [x[0] for x in cr.fetchall()]))
+
def log_model(model, local_registry):
"""
@@ -80,7 +80,7 @@
main registry
"""
- if not model._name: # new in 6.1
+ if not model._name:
return
# persistent models only
@@ -88,16 +88,16 @@
return
model_registry = local_registry.setdefault(
- model._name, {})
+ model._name, {})
if model._inherits:
model_registry['_inherits'] = {'_inherits': unicode(model._inherits)}
for k, v in model._columns.items():
- properties = {
+ properties = {
'type': v._type,
'isfunction': (
isinstance(v, fields.function) and 'function' or ''),
'relation': (
- v._type in ('many2many', 'many2one','one2many')
+ v._type in ('many2many', 'many2one', 'one2many')
and v._obj or ''
),
'required': v.required and 'required' or '',
@@ -123,6 +123,7 @@
if value:
model_registry.setdefault(k, {})[key] = value
+
def get_record_id(cr, module, model, field, mode):
"""
OpenUpgrade: get or create the id from the record table matching
@@ -151,6 +152,7 @@
)
return cr.fetchone()[0]
+
def compare_registries(cr, module, registry, local_registry):
"""
OpenUpgrade: Compare the local registry with the global registry,
=== modified file 'openerp/openupgrade/openupgrade_log.py'
--- openerp/openupgrade/openupgrade_log.py 2014-04-08 11:08:01 +0000
+++ openerp/openupgrade/openupgrade_log.py 2014-05-05 13:52:55 +0000
@@ -1,6 +1,27 @@
# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2011-2014 Therp BV (<http://therp.nl>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
from openupgrade_tools import table_exists
+
def log_xml_id(cr, module, xml_id):
"""
Log xml_ids at load time in the records table.
@@ -11,10 +32,10 @@
won't be called. This can be brought about by installing the
module or updating the 'state' field of the module to 'to install'
or call the server with '--init <module>' and the database argument.
-
+
- Do you get the right results immediately when installing the module?
- No, sorry. This method retrieves the model from the ir_model_table, but when
- the xml id is encountered for the first time, this method is called
+ No, sorry. This method retrieves the model from the ir_model_table, but
+ when the xml id is encountered for the first time, this method is called
before the item is present in this table. Therefore, you will not
get any meaningful results until the *second* time that you 'init'
the module.
@@ -53,4 +74,3 @@
"INSERT INTO openupgrade_record "
"(module, model, name, type) values(%s, %s, %s, %s)",
(module, record[0], xml_id, 'xmlid'))
-
=== modified file 'openerp/openupgrade/openupgrade_tools.py'
--- openerp/openupgrade/openupgrade_tools.py 2014-04-08 11:08:01 +0000
+++ openerp/openupgrade/openupgrade_tools.py 2014-05-05 13:52:55 +0000
@@ -1,8 +1,31 @@
# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# This module copyright (C) 2012-2014 Therp BV (<http://therp.nl>)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+##############################################################################
+
+# A collection of functions split off from openupgrade.py
+# with no or only minimal dependencies
+
+
def table_exists(cr, table):
""" Check whether a certain table or view exists """
cr.execute(
'SELECT count(relname) FROM pg_class WHERE relname = %s',
(table,))
return cr.fetchone()[0] == 1
-
Follow ups