[MERGE] mail: improve record creation with batch operations
PURPOSE Optimize record creation in mail module by adding batch operations. SPECIFICATIONS Compute default followers once at creation for all created records. As the same value is computed for each new record computing it once is sufficient. Log default creation message in batch when having no specific subtype at create. It allows to speedup record creation. For 1000 records, these specific lines take * 2.1s before the commit * 1.2s after the commit LINKS PR #36654 Task 2070602 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -260,9 +260,10 @@ class MailThread(models.AbstractModel):
|
||||
|
||||
# subscribe uid unless asked not to
|
||||
if not self._context.get('mail_create_nosubscribe'):
|
||||
default_followers = self.env['mail.followers']._add_default_followers(self._name, [], self.env.user.partner_id.ids, customer_ids=[])[0][0]
|
||||
for values in vals_list:
|
||||
message_follower_ids = values.get('message_follower_ids') or []
|
||||
message_follower_ids += [(0, 0, fol_vals) for fol_vals in self.env['mail.followers']._add_default_followers(self._name, [], self.env.user.partner_id.ids, customer_ids=[])[0][0]]
|
||||
message_follower_ids += [(0, 0, fol_vals) for fol_vals in default_followers]
|
||||
values['message_follower_ids'] = message_follower_ids
|
||||
|
||||
threads = super(MailThread, self).create(vals_list)
|
||||
@@ -280,13 +281,16 @@ class MailThread(models.AbstractModel):
|
||||
# automatic logging unless asked not to (mainly for various testing purpose)
|
||||
if not self._context.get('mail_create_nolog'):
|
||||
doc_name = self.env['ir.model']._get(self._name).name
|
||||
body = _('%s created') % doc_name
|
||||
threads_no_subtype = self.env[self._name]
|
||||
for thread in threads:
|
||||
subtype = thread._creation_subtype()
|
||||
body = _('%s created') % doc_name
|
||||
if subtype: # if we have a sybtype, post message to notify users from _message_auto_subscribe
|
||||
if subtype: # if we have a subtype, post message to notify users from _message_auto_subscribe
|
||||
thread.sudo().message_post(body=body, subtype_id=subtype.id, author_id=self.env.user.partner_id.id)
|
||||
else:
|
||||
thread._message_log(body=body)
|
||||
threads_no_subtype += thread
|
||||
if threads_no_subtype:
|
||||
threads_no_subtype._message_log_batch(bodies={t.id: body for t in threads_no_subtype})
|
||||
|
||||
# post track template if a tracked field changed
|
||||
if not self._context.get('mail_notrack'):
|
||||
@@ -554,8 +558,9 @@ class MailThread(models.AbstractModel):
|
||||
def _creation_subtype(self):
|
||||
""" Give the subtypes triggered by the creation of a record
|
||||
|
||||
:returns: a subtype browse record or False if no subtype is trigerred
|
||||
:returns: a subtype browse record (empty if no subtype is triggered)
|
||||
"""
|
||||
return self.env['mail.message.subtype']
|
||||
|
||||
def _track_subtype(self, init_values):
|
||||
""" Give the subtypes triggered by the changes on the record according
|
||||
@@ -1019,8 +1024,7 @@ class MailThread(models.AbstractModel):
|
||||
message_dict.pop('parent_id', None)
|
||||
thread = ModelCtx.message_new(message_dict, custom_values)
|
||||
thread_id = thread.id
|
||||
subtype = thread._creation_subtype()
|
||||
subtype_id = subtype.id if subtype else False
|
||||
subtype_id = thread._creation_subtype().id
|
||||
|
||||
# replies to internal message are considered as notes, but parent message
|
||||
# author is added in recipients to ensure he is notified of a private answer
|
||||
|
||||
@@ -65,7 +65,7 @@ class TestMailPerformance(BaseMailPerformance):
|
||||
records = self.env['test_performance.mail'].search([])
|
||||
self.assertEqual(len(records), 5)
|
||||
|
||||
with self.assertQueryCount(__system__=3, demo=3): # test_mail only: 3 - 3
|
||||
with self.assertQueryCount(__system__=3, demo=3):
|
||||
records.write({'name': 'X'})
|
||||
|
||||
@users('__system__', 'demo')
|
||||
@@ -75,7 +75,7 @@ class TestMailPerformance(BaseMailPerformance):
|
||||
records = self.env['test_performance.mail'].search([])
|
||||
self.assertEqual(len(records), 5)
|
||||
|
||||
with self.assertQueryCount(__system__=5, demo=5): # test_mail only: 5 - 5
|
||||
with self.assertQueryCount(__system__=3, demo=3):
|
||||
records.write({'value': 42})
|
||||
|
||||
@users('__system__', 'demo')
|
||||
@@ -89,7 +89,7 @@ class TestMailPerformance(BaseMailPerformance):
|
||||
'partner_id': self.env.ref('base.res_partner_12').id,
|
||||
})
|
||||
|
||||
with self.assertQueryCount(__system__=4, demo=4): # test_mail only: 4 - 4
|
||||
with self.assertQueryCount(__system__=3, demo=3):
|
||||
record.track = 'X'
|
||||
|
||||
@users('__system__', 'demo')
|
||||
@@ -98,27 +98,27 @@ class TestMailPerformance(BaseMailPerformance):
|
||||
""" Create records inheriting from 'mail.thread' (without field tracking). """
|
||||
model = self.env['test_performance.mail']
|
||||
|
||||
with self.assertQueryCount(__system__=3, demo=3): # test_mail only: 3 - 3
|
||||
with self.assertQueryCount(__system__=2, demo=2):
|
||||
model.with_context(tracking_disable=True).create({'name': 'X'})
|
||||
|
||||
@users('__system__', 'demo')
|
||||
@warmup
|
||||
def test_create_mail_with_tracking(self):
|
||||
""" Create records inheriting from 'mail.thread' (with field tracking). """
|
||||
with self.assertQueryCount(__system__=8, demo=8): # test_mail only: 8 - 8
|
||||
with self.assertQueryCount(__system__=7, demo=7):
|
||||
self.env['test_performance.mail'].create({'name': 'X'})
|
||||
|
||||
@users('__system__', 'emp')
|
||||
@warmup
|
||||
def test_create_mail_simple(self):
|
||||
with self.assertQueryCount(__system__=6, emp=6): # test_mail only: 6 - 6
|
||||
with self.assertQueryCount(__system__=6, emp=6):
|
||||
self.env['mail.test.simple'].create({'name': 'Test'})
|
||||
|
||||
@users('__system__', 'emp')
|
||||
@warmup
|
||||
def test_write_mail_simple(self):
|
||||
rec = self.env['mail.test.simple'].create({'name': 'Test'})
|
||||
with self.assertQueryCount(__system__=1, emp=1): # test_mail only: 1 - 1
|
||||
with self.assertQueryCount(__system__=1, emp=1):
|
||||
rec.write({
|
||||
'name': 'Test2',
|
||||
'email_from': 'test@test.com',
|
||||
@@ -150,7 +150,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
def test_adv_activity(self):
|
||||
model = self.env['mail.test.activity']
|
||||
|
||||
with self.assertQueryCount(__system__=7, emp=6): # test_mail only: 7 - 6
|
||||
with self.assertQueryCount(__system__=6, emp=6):
|
||||
model.create({'name': 'Test'})
|
||||
|
||||
@users('__system__', 'emp')
|
||||
@@ -162,7 +162,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
'default_res_model': 'mail.test.activity',
|
||||
})
|
||||
|
||||
with self.assertQueryCount(__system__=10, emp=13): # com runbot: 10 - 13 // test_mail only: 10 - 13
|
||||
with self.assertQueryCount(__system__=6, emp=6):
|
||||
activity = MailActivity.create({
|
||||
'summary': 'Test Activity',
|
||||
'res_id': record.id,
|
||||
@@ -172,7 +172,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
#voip module read activity_type during create leading to one less query in enterprise on action_feedback
|
||||
category = activity.activity_type_id.category
|
||||
|
||||
with self.assertQueryCount(__system__=24, emp=31): # com runbot: 24 - 31 // test_mail only: 24 - 31
|
||||
with self.assertQueryCount(__system__=19, emp=22):
|
||||
activity.action_feedback(feedback='Zizisse Done !')
|
||||
|
||||
@users('__system__', 'emp')
|
||||
@@ -181,7 +181,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
def test_adv_activity_mixin(self):
|
||||
record = self.env['mail.test.activity'].create({'name': 'Test'})
|
||||
|
||||
with self.assertQueryCount(__system__=10, emp=14): # com runbot: 10 - 14 // test_mail only: 10 - 14
|
||||
with self.assertQueryCount(__system__=7, emp=7):
|
||||
activity = record.action_start('Test Start')
|
||||
#read activity_type to normalize cache between enterprise and community
|
||||
#voip module read activity_type during create leading to one less query in enterprise on action_close
|
||||
@@ -189,7 +189,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
|
||||
record.write({'name': 'Dupe write'})
|
||||
|
||||
with self.assertQueryCount(__system__=26, emp=31): # com runbot: 26 - 31 // test_mail only: 26 - 31
|
||||
with self.assertQueryCount(__system__=20, emp=22):
|
||||
record.action_close('Dupe feedback')
|
||||
|
||||
self.assertEqual(record.activity_ids, self.env['mail.activity'])
|
||||
@@ -200,7 +200,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
def test_message_assignation_email(self):
|
||||
self.user_test.write({'notification_type': 'email'})
|
||||
record = self.env['mail.test.track'].create({'name': 'Test'})
|
||||
with self.assertQueryCount(__system__=52, emp=54): # com runbot: 52 - 54 // test_mail only: 52 - 54
|
||||
with self.assertQueryCount(__system__=39, emp=40):
|
||||
record.write({
|
||||
'user_id': self.user_test.id,
|
||||
})
|
||||
@@ -209,7 +209,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
@warmup
|
||||
def test_message_assignation_inbox(self):
|
||||
record = self.env['mail.test.track'].create({'name': 'Test'})
|
||||
with self.assertQueryCount(__system__=32, emp=37): # test_mail only: 32 - 37
|
||||
with self.assertQueryCount(__system__=27, emp=29):
|
||||
record.write({
|
||||
'user_id': self.user_test.id,
|
||||
})
|
||||
@@ -219,7 +219,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
def test_message_log(self):
|
||||
record = self.env['mail.test.simple'].create({'name': 'Test'})
|
||||
|
||||
with self.assertQueryCount(__system__=1, emp=1): # test_mail only: 1 - 1
|
||||
with self.assertQueryCount(__system__=1, emp=1):
|
||||
record._message_log(
|
||||
body='<p>Test _message_log</p>',
|
||||
message_type='comment')
|
||||
@@ -229,7 +229,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
def test_message_log_with_post(self):
|
||||
record = self.env['mail.test.simple'].create({'name': 'Test'})
|
||||
|
||||
with self.assertQueryCount(__system__=6, emp=7): # test_mail only: 6 - 7
|
||||
with self.assertQueryCount(__system__=5, emp=6):
|
||||
record.message_post(
|
||||
body='<p>Test message_post as log</p>',
|
||||
subtype='mail.mt_note',
|
||||
@@ -240,7 +240,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
def test_message_post_no_notification(self):
|
||||
record = self.env['mail.test.simple'].create({'name': 'Test'})
|
||||
|
||||
with self.assertQueryCount(__system__=6, emp=7): # test_mail only: 6 - 7
|
||||
with self.assertQueryCount(__system__=5, emp=6):
|
||||
record.message_post(
|
||||
body='<p>Test Post Performances basic</p>',
|
||||
partner_ids=[],
|
||||
@@ -253,7 +253,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
def test_message_post_one_email_notification(self):
|
||||
record = self.env['mail.test.simple'].create({'name': 'Test'})
|
||||
|
||||
with self.assertQueryCount(__system__=44, emp=47): # com runbot: 44 - 47 // test_mail only: 44 - 47
|
||||
with self.assertQueryCount(__system__=32, emp=33):
|
||||
record.message_post(
|
||||
body='<p>Test Post Performances with an email ping</p>',
|
||||
partner_ids=self.customer.ids,
|
||||
@@ -265,7 +265,7 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
def test_message_post_one_inbox_notification(self):
|
||||
record = self.env['mail.test.simple'].create({'name': 'Test'})
|
||||
|
||||
with self.assertQueryCount(__system__=29, emp=34): # com runbot 29 - 34 // test_mail only: 29 - 34
|
||||
with self.assertQueryCount(__system__=23, emp=25):
|
||||
record.message_post(
|
||||
body='<p>Test Post Performances with an inbox ping</p>',
|
||||
partner_ids=self.user_test.partner_id.ids,
|
||||
@@ -278,10 +278,10 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
def test_message_subscribe_default(self):
|
||||
record = self.env['mail.test.simple'].create({'name': 'Test'})
|
||||
|
||||
with self.assertQueryCount(__system__=6, emp=6): # test_mail only: 6 - 6
|
||||
with self.assertQueryCount(__system__=6, emp=6):
|
||||
record.message_subscribe(partner_ids=self.user_test.partner_id.ids)
|
||||
|
||||
with self.assertQueryCount(__system__=3, emp=3): # test_mail only: 3 - 3
|
||||
with self.assertQueryCount(__system__=3, emp=3):
|
||||
record.message_subscribe(partner_ids=self.user_test.partner_id.ids)
|
||||
|
||||
@mute_logger('odoo.models.unlink')
|
||||
@@ -291,10 +291,10 @@ class TestAdvMailPerformance(BaseMailPerformance):
|
||||
record = self.env['mail.test.simple'].create({'name': 'Test'})
|
||||
subtype_ids = (self.env.ref('test_mail.st_mail_test_simple_external') | self.env.ref('mail.mt_comment')).ids
|
||||
|
||||
with self.assertQueryCount(__system__=5, emp=5): # test_mail only: 5 - 5
|
||||
with self.assertQueryCount(__system__=5, emp=5):
|
||||
record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids)
|
||||
|
||||
with self.assertQueryCount(__system__=2, emp=2): # test_mail only: 2 - 2
|
||||
with self.assertQueryCount(__system__=2, emp=2):
|
||||
record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids)
|
||||
|
||||
|
||||
@@ -362,7 +362,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
'recipient_ids': [(4, pid) for pid in self.partners.ids],
|
||||
})
|
||||
mail_ids = mail.ids
|
||||
with self.assertQueryCount(__system__=16, emp=21): # test_mail only: 16 - 21
|
||||
with self.assertQueryCount(__system__=7, emp=7):
|
||||
self.env['mail.mail'].browse(mail_ids).send()
|
||||
|
||||
self.assertEqual(mail.body_html, '<p>Test</p>')
|
||||
@@ -375,7 +375,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
self.umbrella.message_subscribe(self.user_portal.partner_id.ids)
|
||||
record = self.umbrella.with_user(self.env.user)
|
||||
|
||||
with self.assertQueryCount(__system__=82, emp=85): # com runbot: 82 - 85 // test_mail only: 82 - 85
|
||||
with self.assertQueryCount(__system__=71, emp=72):
|
||||
record.message_post(
|
||||
body='<p>Test Post Performances</p>',
|
||||
message_type='comment',
|
||||
@@ -392,7 +392,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
record = self.umbrella.with_user(self.env.user)
|
||||
template_id = self.env.ref('test_mail.mail_test_tpl').id
|
||||
|
||||
with self.assertQueryCount(__system__=98, emp=103): # com runbot: 98 - 103 // test_mail only: 98 - 103
|
||||
with self.assertQueryCount(__system__=81, emp=82):
|
||||
record.message_post_with_template(template_id, message_type='comment', composition_mode='comment')
|
||||
|
||||
self.assertEqual(record.message_ids[0].body, '<p>Adding stuff on %s</p>' % record.name)
|
||||
@@ -417,7 +417,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
self.assertEqual(rec.message_channel_ids, self.env['mail.channel'])
|
||||
|
||||
# subscribe new followers with forced given subtypes
|
||||
with self.assertQueryCount(__system__=8, emp=8): # test_mail only: 8 - 8
|
||||
with self.assertQueryCount(__system__=8, emp=8):
|
||||
rec.message_subscribe(
|
||||
partner_ids=pids[:4],
|
||||
channel_ids=cids,
|
||||
@@ -428,7 +428,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
self.assertEqual(rec.message_channel_ids, self.channel)
|
||||
|
||||
# subscribe existing and new followers with force=False, meaning only some new followers will be added
|
||||
with self.assertQueryCount(__system__=6, emp=6): # test_mail only: 6 - 6
|
||||
with self.assertQueryCount(__system__=6, emp=6):
|
||||
rec.message_subscribe(
|
||||
partner_ids=pids[:6],
|
||||
channel_ids=cids,
|
||||
@@ -439,7 +439,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
self.assertEqual(rec.message_channel_ids, self.channel)
|
||||
|
||||
# subscribe existing and new followers with force=True, meaning all will have the same subtypes
|
||||
with self.assertQueryCount(__system__=7, emp=7): # test_mail only: 7 - 7
|
||||
with self.assertQueryCount(__system__=7, emp=7):
|
||||
rec.message_subscribe(
|
||||
partner_ids=pids,
|
||||
channel_ids=cids,
|
||||
@@ -461,7 +461,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
'user_id': self.env.uid,
|
||||
})
|
||||
self.assertEqual(rec.message_partner_ids, self.partners | self.env.user.partner_id)
|
||||
with self.assertQueryCount(__system__=52, emp=53): # com runbot: 51 - 53 // test_mail only: 51 - 53
|
||||
with self.assertQueryCount(__system__=39, emp=40):
|
||||
rec.write({'user_id': self.user_portal.id})
|
||||
self.assertEqual(rec.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
|
||||
# write tracking message
|
||||
@@ -481,7 +481,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
customer_id = self.customer.id
|
||||
user_id = self.user_portal.id
|
||||
|
||||
with self.assertQueryCount(__system__=146, emp=149): # com runbot: 146 - 149 // test_mail only: 146 - 149
|
||||
with self.assertQueryCount(__system__=121, emp=122):
|
||||
rec = self.env['mail.test.full'].create({
|
||||
'name': 'Test',
|
||||
'umbrella_id': umbrella_id,
|
||||
@@ -508,7 +508,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
})
|
||||
self.assertEqual(rec.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id)
|
||||
self.assertEqual(len(rec.message_ids), 1)
|
||||
with self.assertQueryCount(__system__=100, emp=106): # com runbot: 100 -106 // test_mail only: 100 - 106
|
||||
with self.assertQueryCount(__system__=84, emp=85):
|
||||
rec.write({
|
||||
'name': 'Test2',
|
||||
'umbrella_id': self.umbrella.id,
|
||||
@@ -544,7 +544,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
})
|
||||
self.assertEqual(rec.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id)
|
||||
|
||||
with self.assertQueryCount(__system__=105, emp=111): # test_mail only: 105 - 111
|
||||
with self.assertQueryCount(__system__=92, emp=93):
|
||||
rec.write({
|
||||
'name': 'Test2',
|
||||
'umbrella_id': umbrella_id,
|
||||
@@ -576,7 +576,7 @@ class TestHeavyMailPerformance(BaseMailPerformance):
|
||||
})
|
||||
self.assertEqual(rec.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id)
|
||||
|
||||
with self.assertQueryCount(__system__=50, emp=63): # test_mail only: 50 - 63
|
||||
with self.assertQueryCount(__system__=33, emp=35):
|
||||
rec.write({
|
||||
'name': 'Test2',
|
||||
'customer_id': customer_id,
|
||||
@@ -713,7 +713,7 @@ class TestMailPerformancePost(BaseMailPerformance):
|
||||
]
|
||||
self.attachements = self.env['ir.attachment'].with_user(self.env.user).create(self.vals)
|
||||
attachement_ids = self.attachements.ids
|
||||
with self.assertQueryCount(emp=175): # com runbot 154 // test_mail only: 132
|
||||
with self.assertQueryCount(emp=118): # runbot 118 // test_mail only: 110
|
||||
self.cr.sql_log = self.warm and self.cr.sql_log_count
|
||||
record.with_context({}).message_post(
|
||||
body='<p>Test body <img src="cid:cid1"> <img src="cid:cid2"></p>',
|
||||
|
||||
Reference in New Issue
Block a user