Merge lp:~camptocamp/openobject-addons/extra-trunk-base_external_referentials-subexport-no-cr into lp:openobject-addons/extra-trunk

Proposed by Guewen Baconnier @ Camptocamp
Status: Needs review
Proposed branch: lp:~camptocamp/openobject-addons/extra-trunk-base_external_referentials-subexport-no-cr
Merge into: lp:openobject-addons/extra-trunk
Diff against target: 64 lines (+19/-6)
1 file modified
base_external_referentials/external_osv.py (+19/-6)
To merge this branch: bzr merge lp:~camptocamp/openobject-addons/extra-trunk-base_external_referentials-subexport-no-cr
Reviewer Review Type Date Requested Status
MagentoERPConnect core editors Pending
Alexandre Fayolle - camptocamp Pending
Review via email: mp+130386@code.launchpad.net

Description of the change

Hi,

This fix the issue:

https://bugs.launchpad.net/magentoerpconnect/+bug/1068174

You'll find the explanation of why the bug occurs in the report.

Alexandre, you'll see what I meant by sub-transactions, even if there are not sub-transactions at database level, obviously, transactions are strictly parallel on the database point of view, but we really nest the exports. I had a misuse of language, but the the result is the same, we are not able to see transaction B from transaction A, because B is opened, committed & closed between the opening, committing & closing of transaction A.

My proposal is based on the current logic used in the import.

When a `export_no_new_cr` key is present in the context, it keeps the current transaction, and that sounds logical because if the export of the category fails, I expect that the export of the product (which wanted to export the category) fails too.

But, this implementation is sensible because if the context is not properly passed all the chain of calls, a new transaction would be opened and we could have the same sort of issues.

I think we would better have to apply the reverse logic, so to never open a new transaction, unless it is asked, and modify the top level exports and imports to use this new method or argument.
But it would require much more changes on the actual code base.

I have one doubt concerning the case when we are in a sub-export and we get an error. We do not rollback the cr, it has to be rollbacked by the main export. We have to raise the exception again to propagate it.
Normally, the `log_failed()` method should do it, because when we are in a sub-export, this latter raise when the key `use_external_log` is not in the context, and it is removed from the context for sub-exports. That's a bit tricky but it should do it.
Again, the problem would be if the context is not properly passed.

To post a comment you must log in.

Unmerged revisions

5823. By Guewen Baconnier @ Camptocamp <email address hidden> on 2012-10-18

[FIX] issue lp:1068174 records created on magento during an sub-export are not visible in the export

When a new transaction is opened for an export and this export have sub-exports (exports in the mappings for example),
the sub-exports must not open new transactions, otherwise, the transaction of the main export will not be able
to read the data written by the sub-exports (external ids created principally).

This implementation is sensible because the `export_no_new_cr` has to be propagated through the context,
and if the context chain is broken, it will open a new transaction regardless. It would maybe be better in
the other way, no new cr by default, and explicitely ask for a new cr on top level exports, but it would require
to search and change all the top level export, and do the same for the imports to have a consistant logic between them.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'base_external_referentials/external_osv.py'
2--- base_external_referentials/external_osv.py 2012-07-25 14:06:17 +0000
3+++ base_external_referentials/external_osv.py 2012-10-18 15:44:20 +0000
4@@ -536,6 +536,9 @@
5 raise osv.except_osv(_('External Import Error'), _("The object imported need an external_id, maybe the mapping doesn't exist for the object : %s" %self._name))
6 external_id = vals['external_id']
7 del vals['external_id']
8+ _logger.debug(
9+ "Starting import of external resource %s with external id %s %s new cursor %s",
10+ self._name, external_id, 'without' if record_cr is None else 'with', record_cr or cr)
11 cid, wid = self._ext_import_one(
12 record_cr or cr, uid, external_id,
13 vals,
14@@ -819,18 +822,26 @@
15
16 report_line_obj = self.pool.get('external.report.line')
17
18- export_ctx = dict(context)
19+ export_ctx = dict(context, export_no_new_cr=True)
20 # avoid to use external logs in submethods as they are handle at this level
21 export_ctx.pop('use_external_log', False)
22
23- record_cr = pooler.get_db(cr.dbname).cursor()
24+ record_cr = None
25+ if not context.get('export_no_new_cr'):
26+ record_cr = pooler.get_db(cr.dbname).cursor()
27+
28 cid = wid = False
29+ _logger.debug(
30+ "Starting export of resource %s with openerp id %s %s new cursor %s",
31+ self._name, record_data['id'], 'without' if record_cr is None else 'with', record_cr or cr)
32 try:
33 cid, wid = self._ext_export_one(
34- record_cr, uid, record_data, referential_id, defaults=defaults, context=export_ctx)
35+ record_cr or cr, uid, record_data, referential_id, defaults=defaults, context=export_ctx)
36 except (MappingError, osv.except_osv, xmlrpclib.Fault):
37 _logger.exception('error during export of %s (id: %s) with referential_id %s. Creating a report line', record_data.get('name', 'NONAME'), record_data.get('id'), referential_id)
38- record_cr.rollback()
39+ if record_cr:
40+ record_cr.rollback()
41+
42 report_line_obj.log_failed(
43 cr, uid,
44 self._name,
45@@ -840,7 +851,8 @@
46 defaults=defaults,
47 context=context)
48 else:
49- record_cr.commit()
50+ if record_cr:
51+ record_cr.commit()
52 report_line_obj.log_success(
53 cr, uid,
54 self._name,
55@@ -849,7 +861,8 @@
56 res_id=record_data['id'],
57 context=context)
58 finally:
59- record_cr.close()
60+ if record_cr:
61+ record_cr.close()
62 return cid, wid
63
64 def ext_export(self, cr, uid, ids, external_referential_ids=[], defaults={}, context=None):

Subscribers

People subscribed via source and target branches