changeset bfc90c50b591 in trytond:default details: https://hg.tryton.org/trytond?cmd=changeset;node=bfc90c50b591 description: Always use search method on translations
This ensure to have always the same order when selecting the record out of many duplicates (which can happen as there is no unique constraint since r 426276806f60). issue8705 review260271002 diffstat: trytond/ir/translation.py | 80 +++++++++++++++++------------------------ trytond/tests/test_modelsql.py | 24 ++++++++++++ 2 files changed, 58 insertions(+), 46 deletions(-) diffs (162 lines): diff -r f1ac853b1006 -r bfc90c50b591 trytond/ir/translation.py --- a/trytond/ir/translation.py Wed Oct 16 21:24:06 2019 +0200 +++ b/trytond/ir/translation.py Wed Oct 16 21:31:25 2019 +0200 @@ -11,7 +11,6 @@ from sql import Column, Null, Literal from sql.functions import Substring, Position from sql.conditionals import Case -from sql.operators import Or, And from sql.aggregate import Max from genshi.filters.i18n import extract as genshi_extract @@ -24,7 +23,7 @@ from ..model import ModelView, ModelSQL, fields from ..wizard import Wizard, StateView, StateTransition, StateAction, \ Button -from ..tools import file_open, reduce_ids, grouped_slice, cursor_dict +from ..tools import file_open, grouped_slice, cursor_dict from ..pyson import PYSONEncoder, Eval from ..transaction import Transaction from ..pool import Pool @@ -346,27 +345,20 @@ translations.update( cls.get_ids(name, ttype, parent_lang, to_fetch)) - transaction = Transaction() - cursor = transaction.connection.cursor() - table = cls.__table__() - fuzzy_sql = table.fuzzy == False if Transaction().context.get('fuzzy_translation', False): - fuzzy_sql = None - in_max = transaction.database.IN_MAX // 7 - for sub_to_fetch in grouped_slice(to_fetch, in_max): - red_sql = reduce_ids(table.res_id, sub_to_fetch) - where = And(((table.lang == lang), - (table.type == ttype), - (table.name == name), - (table.value != ''), - (table.value != Null), - red_sql, - )) - if fuzzy_sql: - where &= fuzzy_sql - cursor.execute(*table.select(table.res_id, table.value, - where=where)) - translations.update(cursor) + fuzzy_clause = [] + else: + fuzzy_clause = [('fuzzy', '=', False)] + for sub_to_fetch in grouped_slice(to_fetch): + for translation in cls.search([ + ('lang', '=', lang), + ('type', '=', ttype), + ('name', '=', name), + ('value', '!=', ''), + ('value', '!=', None), + ('res_id', 'in', list(sub_to_fetch)), + ] + fuzzy_clause): + translations[translation.res_id] = translation.value # Don't store fuzzy translation in cache if not Transaction().context.get('fuzzy_translation', False): for res_id in to_fetch: @@ -526,10 +518,8 @@ res = {} parent_args = [] parent_langs = [] - clause = [] + clauses = [] transaction = Transaction() - cursor = transaction.connection.cursor() - table = cls.__table__() if len(args) > transaction.database.IN_MAX: for sub_args in grouped_slice(args): res.update(cls.get_sources(list(sub_args))) @@ -552,17 +542,18 @@ parent_args.append((name, ttype, parent_lang, source)) parent_langs.append(lang) res[(name, ttype, lang, source)] = None - where = And(((table.lang == lang), - (table.type == ttype), - (table.name == name), - (table.value != ''), - (table.value != Null), - (table.fuzzy == False), - (table.res_id == -1), - )) + clause = [ + ('lang', '=', lang), + ('type', '=', ttype), + ('name', '=', name), + ('value', '!=', ''), + ('value', '!=', None), + ('fuzzy', '=', False), + ('res_id', '=', -1), + ] if source is not None: - where &= table.src == source - clause.append(where) + clause.append(('src', '=', source)) + clauses.append(clause) # Get parent transactions if parent_args: @@ -572,17 +563,14 @@ res[(name, ttype, lang, source)] = parent_src[ (name, ttype, parent_lang, source)] - if clause: - in_max = transaction.database.IN_MAX // 7 - for sub_clause in grouped_slice(clause, in_max): - cursor.execute(*table.select( - table.lang, table.type, table.name, table.src, - table.value, - where=Or(list(sub_clause)))) - for lang, ttype, name, source, value in cursor.fetchall(): - if (name, ttype, lang, source) not in args: - source = None - res[(name, ttype, lang, source)] = value + in_max = transaction.database.IN_MAX // 7 + for sub_clause in grouped_slice(clauses, in_max): + for translation in cls.search(['OR'] + list(sub_clause)): + key = (translation.name, translation.type, + translation.name, translation.name, translation.src) + if key not in args: + key = key[:-1] + (None,) + res[key] = translation.value for key in to_cache: cls._translation_cache.set(key, res[key]) return res diff -r f1ac853b1006 -r bfc90c50b591 trytond/tests/test_modelsql.py --- a/trytond/tests/test_modelsql.py Wed Oct 16 21:24:06 2019 +0200 +++ b/trytond/tests/test_modelsql.py Wed Oct 16 21:31:25 2019 +0200 @@ -701,6 +701,30 @@ self.assertEqual(record.name, "Foo") self.assertEqual(other.name, "Bar") + @with_transaction() + def test_read_last_translation(self): + "Test read last translation record" + pool = Pool() + Model = pool.get('test.modelsql.translation') + Translation = pool.get('ir.translation') + + with Transaction().set_context(language=self.default_language): + record, = Model.create([{'name': "Foo"}]) + with Transaction().set_context(language=self.other_language): + Model.write([record], {'name': "Bar"}) + other = Model(record.id) + + translation, = Translation.search([ + ('lang', '=', self.other_language), + ('name', '=', 'test.modelsql.translation,name'), + ('type', '=', 'model'), + ('res_id', '=', record.id), + ]) + Translation.copy([translation], default={'value': "Baz"}) + + self.assertEqual(record.name, "Foo") + self.assertEqual(other.name, "Baz") + def suite(): suite_ = unittest.TestSuite()