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>

[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
=== modified file 'base_external_referentials/external_osv.py'
--- base_external_referentials/external_osv.py 2012-07-25 14:06:17 +0000
+++ base_external_referentials/external_osv.py 2012-10-18 15:44:20 +0000
@@ -536,6 +536,9 @@
536 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))536 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))
537 external_id = vals['external_id']537 external_id = vals['external_id']
538 del vals['external_id']538 del vals['external_id']
539 _logger.debug(
540 "Starting import of external resource %s with external id %s %s new cursor %s",
541 self._name, external_id, 'without' if record_cr is None else 'with', record_cr or cr)
539 cid, wid = self._ext_import_one(542 cid, wid = self._ext_import_one(
540 record_cr or cr, uid, external_id,543 record_cr or cr, uid, external_id,
541 vals,544 vals,
@@ -819,18 +822,26 @@
819822
820 report_line_obj = self.pool.get('external.report.line')823 report_line_obj = self.pool.get('external.report.line')
821824
822 export_ctx = dict(context)825 export_ctx = dict(context, export_no_new_cr=True)
823 # avoid to use external logs in submethods as they are handle at this level826 # avoid to use external logs in submethods as they are handle at this level
824 export_ctx.pop('use_external_log', False)827 export_ctx.pop('use_external_log', False)
825828
826 record_cr = pooler.get_db(cr.dbname).cursor()829 record_cr = None
830 if not context.get('export_no_new_cr'):
831 record_cr = pooler.get_db(cr.dbname).cursor()
832
827 cid = wid = False833 cid = wid = False
834 _logger.debug(
835 "Starting export of resource %s with openerp id %s %s new cursor %s",
836 self._name, record_data['id'], 'without' if record_cr is None else 'with', record_cr or cr)
828 try:837 try:
829 cid, wid = self._ext_export_one(838 cid, wid = self._ext_export_one(
830 record_cr, uid, record_data, referential_id, defaults=defaults, context=export_ctx)839 record_cr or cr, uid, record_data, referential_id, defaults=defaults, context=export_ctx)
831 except (MappingError, osv.except_osv, xmlrpclib.Fault):840 except (MappingError, osv.except_osv, xmlrpclib.Fault):
832 _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)841 _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)
833 record_cr.rollback()842 if record_cr:
843 record_cr.rollback()
844
834 report_line_obj.log_failed(845 report_line_obj.log_failed(
835 cr, uid,846 cr, uid,
836 self._name,847 self._name,
@@ -840,7 +851,8 @@
840 defaults=defaults,851 defaults=defaults,
841 context=context)852 context=context)
842 else:853 else:
843 record_cr.commit()854 if record_cr:
855 record_cr.commit()
844 report_line_obj.log_success(856 report_line_obj.log_success(
845 cr, uid,857 cr, uid,
846 self._name,858 self._name,
@@ -849,7 +861,8 @@
849 res_id=record_data['id'],861 res_id=record_data['id'],
850 context=context)862 context=context)
851 finally:863 finally:
852 record_cr.close()864 if record_cr:
865 record_cr.close()
853 return cid, wid866 return cid, wid
854867
855def ext_export(self, cr, uid, ids, external_referential_ids=[], defaults={}, context=None):868def ext_export(self, cr, uid, ids, external_referential_ids=[], defaults={}, context=None):

Subscribers

People subscribed via source and target branches