From 13957b62811a0606161cff013e0b752dccbb3295 Mon Sep 17 00:00:00 2001 From: "Chong Wang (cwg)" Date: Mon, 7 Aug 2023 14:46:46 +0200 Subject: [PATCH] [FIX] core: support cr.execute_values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit psycopg2.extras.execute_values was introduced in PR #101237 however it pypasses the override logic for cr.execute. As a result 1. --log-sql cannot log these queries 2. assertQueryCount cannot notice these queries ... This commit create a new api cr.execute_values to support the same SQL feature without losing the override logic for cr.execute closes odoo/odoo#131190 Related: odoo/enterprise#47374 Signed-off-by: Rémy Voet (ryv) --- .../crm/tests/test_crm_lead_convert_mass.py | 6 +- .../tests/test_sync_odoo2google.py | 2 +- .../hr_holidays/tests/test_company_leave.py | 2 +- .../tests/test_performance.py | 6 +- addons/sale_stock/tests/test_create_perf.py | 8 +- addons/test_mail/tests/test_performance.py | 76 +++++++++---------- .../tests/test_mail_performance.py | 2 +- addons/test_mail_full/tests/test_rating.py | 4 +- .../tests/test_sms_performance.py | 6 +- .../website_sale/models/product_template.py | 3 +- odoo/addons/base/models/ir_model.py | 4 +- .../tests/test_performance.py | 20 ++--- odoo/fields.py | 4 +- odoo/sql_db.py | 13 +++- 14 files changed, 83 insertions(+), 73 deletions(-) diff --git a/addons/crm/tests/test_crm_lead_convert_mass.py b/addons/crm/tests/test_crm_lead_convert_mass.py index c4c9a395be4..29203142dcb 100644 --- a/addons/crm/tests/test_crm_lead_convert_mass.py +++ b/addons/crm/tests/test_crm_lead_convert_mass.py @@ -24,7 +24,7 @@ class TestLeadConvertMass(crm_common.TestLeadConvertMassCommon): with self.assertQueryCount(user_sales_manager=0): test_leads = self.env['crm.lead'].browse(test_leads.ids) - with self.assertQueryCount(user_sales_manager=593): # crm 537 / com 541 / ent 536 + with self.assertQueryCount(user_sales_manager=627): # crm 537 / com 541 / ent 536 test_leads._handle_salesmen_assignment(user_ids=user_ids, team_id=False) self.assertEqual(test_leads.team_id, self.sales_team_convert | self.sales_team_1) @@ -42,7 +42,7 @@ class TestLeadConvertMass(crm_common.TestLeadConvertMassCommon): with self.assertQueryCount(user_sales_manager=0): test_leads = self.env['crm.lead'].browse(test_leads.ids) - with self.assertQueryCount(user_sales_manager=548): # crm 521 / com 516 / ent 516 + with self.assertQueryCount(user_sales_manager=580): # crm 521 / com 516 / ent 516 test_leads._handle_salesmen_assignment(user_ids=user_ids, team_id=team_id) self.assertEqual(test_leads.team_id, self.sales_team_convert) @@ -167,7 +167,7 @@ class TestLeadConvertMass(crm_common.TestLeadConvertMassCommon): user_ids = self.assign_users.ids # randomness: at least 1 query - with self.assertQueryCount(user_sales_manager=1712): # crm 1410 / com 1677 / ent 1685 + with self.assertQueryCount(user_sales_manager=1797): # crm 1410 / com 1677 / ent 1685 mass_convert = self.env['crm.lead2opportunity.partner.mass'].with_context({ 'active_model': 'crm.lead', 'active_ids': test_leads.ids, diff --git a/addons/google_calendar/tests/test_sync_odoo2google.py b/addons/google_calendar/tests/test_sync_odoo2google.py index 3fd71aa1914..4dc754ae249 100644 --- a/addons/google_calendar/tests/test_sync_odoo2google.py +++ b/addons/google_calendar/tests/test_sync_odoo2google.py @@ -106,7 +106,7 @@ class TestSyncOdoo2Google(TestSyncGoogle): }) partner_model = self.env.ref('base.model_res_partner') partner = self.env['res.partner'].search([], limit=1) - with self.assertQueryCount(__system__=72): + with self.assertQueryCount(__system__=84): event = self.env['calendar.event'].create({ 'name': "Event", 'start': datetime(2020, 1, 15, 8, 0), diff --git a/addons/hr_holidays/tests/test_company_leave.py b/addons/hr_holidays/tests/test_company_leave.py index 2fddbf66d7f..15a44e91f90 100644 --- a/addons/hr_holidays/tests/test_company_leave.py +++ b/addons/hr_holidays/tests/test_company_leave.py @@ -327,7 +327,7 @@ class TestCompanyLeave(TransactionCase): }) company_leave._compute_date_from_to() - with self.assertQueryCount(__system__=607, admin=867): # 770 community + with self.assertQueryCount(__system__=611, admin=867): # 770 community # Original query count: 1987 # Without tracking/activity context keys: 5154 company_leave.action_validate() diff --git a/addons/hr_work_entry_holidays/tests/test_performance.py b/addons/hr_work_entry_holidays/tests/test_performance.py index 5327a1b6f68..ce12484cf49 100644 --- a/addons/hr_work_entry_holidays/tests/test_performance.py +++ b/addons/hr_work_entry_holidays/tests/test_performance.py @@ -32,7 +32,7 @@ class TestWorkEntryHolidaysPerformance(TestWorkEntryHolidaysBase): self.richard_emp.generate_work_entries(date(2018, 1, 1), date(2018, 1, 2)) leave = self.create_leave(datetime(2018, 1, 1, 7, 0), datetime(2018, 1, 1, 18, 0)) - with self.assertQueryCount(__system__=98, admin=102): + with self.assertQueryCount(__system__=99, admin=102): leave.action_validate() leave.action_refuse() @@ -48,7 +48,7 @@ class TestWorkEntryHolidaysPerformance(TestWorkEntryHolidaysBase): @users('__system__', 'admin') @warmup def test_performance_leave_create(self): - with self.assertQueryCount(__system__=44, admin=44): + with self.assertQueryCount(__system__=45, admin=45): leave = self.create_leave(datetime(2018, 1, 1, 7, 0), datetime(2018, 1, 1, 18, 0)) leave.action_refuse() @@ -57,7 +57,7 @@ class TestWorkEntryHolidaysPerformance(TestWorkEntryHolidaysBase): def test_performance_leave_confirm(self): leave = self.create_leave(datetime(2018, 1, 1, 7, 0), datetime(2018, 1, 1, 18, 0)) leave.action_draft() - with self.assertQueryCount(__system__=40, admin=40): + with self.assertQueryCount(__system__=41, admin=40): leave.action_confirm() leave.state = 'refuse' diff --git a/addons/sale_stock/tests/test_create_perf.py b/addons/sale_stock/tests/test_create_perf.py index 89bd3f382c5..d8e352aee7f 100644 --- a/addons/sale_stock/tests/test_create_perf.py +++ b/addons/sale_stock/tests/test_create_perf.py @@ -50,7 +50,7 @@ class TestPERF(common.TransactionCase): @warmup @prepare def test_empty_sale_order_creation_perf(self): - with self.assertQueryCount(admin=32): + with self.assertQueryCount(admin=33): self.env['sale.order'].create({ 'partner_id': self.partners[0].id, 'user_id': self.salesmans[0].id, @@ -65,7 +65,7 @@ class TestPERF(common.TransactionCase): # + 1 warehouse fetch # + 1 query to get analytic default account # + 1 followers queries ? - with self.assertQueryCount(admin=36): + with self.assertQueryCount(admin=37): self.env['sale.order'].create([{ 'partner_id': self.partners[0].id, 'user_id': self.salesmans[0].id, @@ -77,7 +77,7 @@ class TestPERF(common.TransactionCase): def test_dummy_sales_orders_batch_creation_perf(self): """ Dummy SOlines (notes/sections) should not add any custom queries other than their insert""" # + 2 SOL (batched) insert - with self.assertQueryCount(admin=39): + with self.assertQueryCount(admin=40): self.env['sale.order'].create([{ 'partner_id': self.partners[0].id, 'user_id': self.salesmans[0].id, @@ -96,7 +96,7 @@ class TestPERF(common.TransactionCase): # + 2 SQL insert # + 2 queries to get analytic default tags # + 9 follower queries ? - with self.assertQueryCount(admin=48): + with self.assertQueryCount(admin=49): self.env['sale.order'].create([{ 'partner_id': self.partners[0].id, 'user_id': self.salesmans[0].id, diff --git a/addons/test_mail/tests/test_performance.py b/addons/test_mail/tests/test_performance.py index c6b9e566eff..45e5862f871 100644 --- a/addons/test_mail/tests/test_performance.py +++ b/addons/test_mail/tests/test_performance.py @@ -225,19 +225,19 @@ class TestBaseMailPerformance(BaseMailPerformance): @warmup def test_create_mail_with_tracking(self): """ Create records inheriting from 'mail.thread' (with field tracking). """ - with self.assertQueryCount(admin=7, demo=7): + with self.assertQueryCount(admin=8, demo=8): self.env['mail.performance.thread'].create({'name': 'X'}) @users('admin', 'employee') @warmup def test_create_mail_simple(self): - with self.assertQueryCount(admin=6, employee=6): + with self.assertQueryCount(admin=7, employee=7): self.env['mail.test.simple'].create({'name': 'Test'}) @users('admin', 'employee') @warmup def test_create_mail_simple_multi(self): - with self.assertQueryCount(admin=6, employee=6): + with self.assertQueryCount(admin=7, employee=7): self.env['mail.test.simple'].create([{'name': 'Test'}] * 5) @users('admin', 'employee') @@ -265,7 +265,7 @@ class TestMailAPIPerformance(BaseMailPerformance): def test_adv_activity(self): model = self.env['mail.test.activity'] - with self.assertQueryCount(admin=6, employee=6): + with self.assertQueryCount(admin=7, employee=7): model.create({'name': 'Test'}) @users('admin', 'employee') @@ -330,7 +330,7 @@ class TestMailAPIPerformance(BaseMailPerformance): record.write({'name': 'Dupe write'}) - with self.assertQueryCount(admin=16, employee=16): # com+tm 15/15 + with self.assertQueryCount(admin=17, employee=17): # com+tm 15/15 record.action_close('Dupe feedback', attachment_ids=attachments.ids) # notifications @@ -346,7 +346,7 @@ class TestMailAPIPerformance(BaseMailPerformance): def test_mail_composer(self): test_record, _test_template = self._create_test_records() customer_id = self.customer.id - with self.assertQueryCount(admin=4, employee=4): + with self.assertQueryCount(admin=5, employee=5): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, @@ -356,7 +356,7 @@ class TestMailAPIPerformance(BaseMailPerformance): 'partner_ids': [(4, customer_id)], }) - with self.assertQueryCount(admin=36, employee=36): # com 35/35 + with self.assertQueryCount(admin=39, employee=39): # com 35/35 composer._action_send_mail() @users('admin', 'employee') @@ -366,7 +366,7 @@ class TestMailAPIPerformance(BaseMailPerformance): test_record, _test_template = self._create_test_records() customer = self.env['res.partner'].browse(self.customer.ids) attachments = self.env['ir.attachment'].with_user(self.env.user).create(self.test_attachments_vals) - with self.assertQueryCount(admin=4, employee=4): + with self.assertQueryCount(admin=6, employee=6): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, @@ -377,7 +377,7 @@ class TestMailAPIPerformance(BaseMailPerformance): 'partner_ids': [(4, customer.id)], }) - with self.assertQueryCount(admin=36, employee=36): # com 35/35 + with self.assertQueryCount(admin=40, employee=40): # com 35/35 composer._action_send_mail() @users('admin', 'employee') @@ -401,7 +401,7 @@ class TestMailAPIPerformance(BaseMailPerformance): composer_form.attachment_ids.add(attachment) composer = composer_form.save() - with self.assertQueryCount(admin=49, employee=49): # tm+com 46/46 + with self.assertQueryCount(admin=53, employee=53): # tm+com 46/46 composer._action_send_mail() # notifications @@ -415,7 +415,7 @@ class TestMailAPIPerformance(BaseMailPerformance): def test_mail_composer_mass_w_template(self): _partners, test_records, test_template = self._create_test_records_for_batch() - with self.assertQueryCount(admin=3, employee=3): + with self.assertQueryCount(admin=4, employee=4): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', 'default_model': test_records._name, @@ -423,7 +423,7 @@ class TestMailAPIPerformance(BaseMailPerformance): 'default_template_id': test_template.id, }).create({}) - with self.assertQueryCount(admin=108, employee=111), self.mock_mail_gateway(): + with self.assertQueryCount(admin=138, employee=131), self.mock_mail_gateway(): composer._action_send_mail() self.assertEqual(len(self._new_mails), 10) @@ -434,7 +434,7 @@ class TestMailAPIPerformance(BaseMailPerformance): def test_mail_composer_nodelete(self): test_record, _test_template = self._create_test_records() customer_id = self.customer.id - with self.assertQueryCount(admin=4, employee=4): + with self.assertQueryCount(admin=5, employee=5): composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, @@ -445,7 +445,7 @@ class TestMailAPIPerformance(BaseMailPerformance): 'partner_ids': [(4, customer_id)], }) - with self.assertQueryCount(admin=36, employee=36): # com 35/35 + with self.assertQueryCount(admin=39, employee=39): # com 35/35 composer._action_send_mail() @users('admin', 'employee') @@ -455,7 +455,7 @@ class TestMailAPIPerformance(BaseMailPerformance): test_record, test_template = self._create_test_records() test_template.write({'attachment_ids': [(5, 0)]}) - with self.assertQueryCount(admin=24, employee=24): # tm 15/15 / com 23/23 + with self.assertQueryCount(admin=26, employee=26): # tm 15/15 / com 23/23 composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, @@ -463,7 +463,7 @@ class TestMailAPIPerformance(BaseMailPerformance): 'default_template_id': test_template.id, }).create({}) - with self.assertQueryCount(admin=37, employee=37): # com 36/36 + with self.assertQueryCount(admin=40, employee=40): # com 36/36 composer._action_send_mail() # notifications @@ -479,7 +479,7 @@ class TestMailAPIPerformance(BaseMailPerformance): def test_mail_composer_w_template_attachments(self): test_record, test_template = self._create_test_records() - with self.assertQueryCount(admin=24, employee=24): # tm 15/15 / com 23/23 + with self.assertQueryCount(admin=27, employee=27): # tm 15/15 / com 23/23 composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'comment', 'default_model': test_record._name, @@ -487,7 +487,7 @@ class TestMailAPIPerformance(BaseMailPerformance): 'default_template_id': test_template.id, }).create({}) - with self.assertQueryCount(admin=44, employee=44): # com 43/43 + with self.assertQueryCount(admin=49, employee=49): # com 43/43 composer._action_send_mail() # notifications @@ -519,7 +519,7 @@ class TestMailAPIPerformance(BaseMailPerformance): ) composer = composer_form.save() - with self.assertQueryCount(admin=45, employee=45): # com 44/44 + with self.assertQueryCount(admin=48, employee=48): # com 44/44 composer._action_send_mail() # notifications @@ -549,7 +549,7 @@ class TestMailAPIPerformance(BaseMailPerformance): ) composer = composer_form.save() - with self.assertQueryCount(admin=62, employee=62): # com 61/61 + with self.assertQueryCount(admin=67, employee=67): # com 61/61 composer._action_send_mail() # notifications @@ -576,7 +576,7 @@ class TestMailAPIPerformance(BaseMailPerformance): # use another user already pre-defined with the email notification type, # so the ormcache is preserved. record = self.env['mail.test.track'].create({'name': 'Test'}) - with self.assertQueryCount(admin=38, employee=38): + with self.assertQueryCount(admin=41, employee=41): record.write({ 'user_id': self.user_test_email.id, }) @@ -585,7 +585,7 @@ class TestMailAPIPerformance(BaseMailPerformance): @warmup def test_message_assignation_inbox(self): record = self.env['mail.test.track'].create({'name': 'Test'}) - with self.assertQueryCount(admin=20, employee=20): # com 19/9 + with self.assertQueryCount(admin=22, employee=22): # com 19/9 record.write({ 'user_id': self.user_test_inbox.id, }) @@ -659,7 +659,7 @@ class TestMailAPIPerformance(BaseMailPerformance): def test_message_post_one_email_notification(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(admin=31, employee=31): # com 30/30 + with self.assertQueryCount(admin=33, employee=33): # com 30/30 record.message_post( body=Markup('

Test Post Performances with an email ping

'), partner_ids=self.customer.ids, @@ -671,7 +671,7 @@ class TestMailAPIPerformance(BaseMailPerformance): def test_message_post_one_inbox_notification(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(admin=19, employee=19): # com 18/18 + with self.assertQueryCount(admin=20, employee=20): # com 18/18 record.message_post( body=Markup('

Test Post Performances with an inbox ping

'), partner_ids=self.user_test.partner_id.ids, @@ -684,7 +684,7 @@ class TestMailAPIPerformance(BaseMailPerformance): def test_message_subscribe_default(self): record = self.env['mail.test.simple'].create({'name': 'Test'}) - with self.assertQueryCount(admin=5, employee=5): + with self.assertQueryCount(admin=6, employee=6): record.message_subscribe(partner_ids=self.user_test.partner_id.ids) with self.assertQueryCount(admin=3, employee=3): @@ -697,7 +697,7 @@ class TestMailAPIPerformance(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(admin=4, employee=4): + with self.assertQueryCount(admin=5, employee=5): record.message_subscribe(partner_ids=self.user_test.partner_id.ids, subtype_ids=subtype_ids) with self.assertQueryCount(admin=2, employee=2): @@ -962,7 +962,7 @@ class TestMailComplexPerformance(BaseMailPerformance): record = self.container.with_user(self.env.user) # about 20 (19?) queries per additional customer group - with self.assertQueryCount(admin=56, employee=55): # com 55/54 + with self.assertQueryCount(admin=58, employee=57): # com 55/54 record.message_post( body=Markup('

Test Post Performances

'), message_type='comment', @@ -980,7 +980,7 @@ class TestMailComplexPerformance(BaseMailPerformance): template = self.env.ref('test_mail.mail_test_container_tpl') # about 20 (19 ?) queries per additional customer group - with self.assertQueryCount(admin=63, employee=62): # com 62/61 + with self.assertQueryCount(admin=67, employee=66): # com 62/61 record.message_post_with_source( template, message_type='comment', @@ -996,7 +996,7 @@ class TestMailComplexPerformance(BaseMailPerformance): def test_complex_message_post_view(self): _partners, test_records, test_template = self._create_test_records_for_batch() - with self.assertQueryCount(admin=3, employee=3): + with self.assertQueryCount(admin=4, employee=4): _composer = self.env['mail.compose.message'].with_context({ 'default_composition_mode': 'mass_mail', 'default_model': test_records._name, @@ -1031,7 +1031,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id) # subscribe new followers with forced given subtypes - with self.assertQueryCount(admin=3, employee=3): + with self.assertQueryCount(admin=4, employee=4): rec.message_subscribe( partner_ids=pids[:4], subtype_ids=subtype_ids @@ -1040,7 +1040,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id | self.partners[:4]) # subscribe existing and new followers with force=False, meaning only some new followers will be added - with self.assertQueryCount(admin=4, employee=4): + with self.assertQueryCount(admin=5, employee=5): rec.message_subscribe( partner_ids=pids[:6], subtype_ids=None @@ -1049,7 +1049,7 @@ class TestMailComplexPerformance(BaseMailPerformance): self.assertEqual(rec1.message_partner_ids, self.env.user.partner_id | self.user_portal.partner_id | self.partners[:6]) # subscribe existing and new followers with force=True, meaning all will have the same subtypes - with self.assertQueryCount(admin=3, employee=3): + with self.assertQueryCount(admin=4, employee=4): rec.message_subscribe( partner_ids=pids, subtype_ids=subtype_ids @@ -1070,7 +1070,7 @@ class TestMailComplexPerformance(BaseMailPerformance): }) rec1 = rec.with_context(active_test=False) # to see inactive records self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id) - with self.assertQueryCount(admin=38, employee=38): + with self.assertQueryCount(admin=41, employee=41): rec.write({'user_id': self.user_portal.id}) self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id) # write tracking message @@ -1090,7 +1090,7 @@ class TestMailComplexPerformance(BaseMailPerformance): customer_id = self.customer.id user_id = self.user_portal.id - with self.assertQueryCount(admin=92, employee=92): + with self.assertQueryCount(admin=98, employee=98): rec = self.env['mail.test.ticket'].create({ 'name': 'Test', 'container_id': container_id, @@ -1119,7 +1119,7 @@ class TestMailComplexPerformance(BaseMailPerformance): rec1 = rec.with_context(active_test=False) # to see inactive records self.assertEqual(rec1.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id) self.assertEqual(len(rec1.message_ids), 1) - with self.assertQueryCount(admin=58, employee=58): + with self.assertQueryCount(admin=61, employee=61): rec.write({ 'name': 'Test2', 'container_id': self.container.id, @@ -1156,7 +1156,7 @@ class TestMailComplexPerformance(BaseMailPerformance): rec1 = rec.with_context(active_test=False) # to see inactive records self.assertEqual(rec1.message_partner_ids, self.user_portal.partner_id | self.env.user.partner_id) - with self.assertQueryCount(admin=64, employee=64): + with self.assertQueryCount(admin=67, employee=67): rec.write({ 'name': 'Test2', 'container_id': container_id, @@ -1189,7 +1189,7 @@ class TestMailComplexPerformance(BaseMailPerformance): rec1 = rec.with_context(active_test=False) # to see inactive records self.assertEqual(rec1.message_partner_ids, self.partners | self.env.user.partner_id | self.user_portal.partner_id) - with self.assertQueryCount(admin=32, employee=32): + with self.assertQueryCount(admin=33, employee=33): rec.write({ 'name': 'Test2', 'customer_id': customer_id, @@ -1346,7 +1346,7 @@ class TestMailHeavyPerformancePost(BaseMailPerformance): attachments = self.env['ir.attachment'].with_user(self.env.user).create(self.test_attachments_vals) # enable_logging = self.cr._enable_logging() if self.warm else nullcontext() # with self.assertQueryCount(employee=63), enable_logging: - with self.assertQueryCount(employee=61): # com 60 + with self.assertQueryCount(employee=65): # com 60 record_container.with_context({}).message_post( body=Markup('

Test body

'), subject='Test Subject', diff --git a/addons/test_mail_full/tests/test_mail_performance.py b/addons/test_mail_full/tests/test_mail_performance.py index 62fa923eb75..7eeaa92f41f 100644 --- a/addons/test_mail_full/tests/test_mail_performance.py +++ b/addons/test_mail_full/tests/test_mail_performance.py @@ -91,7 +91,7 @@ class TestMailPerformance(FullBaseMailPerformance): record_ticket = self.env['mail.test.ticket.mc'].browse(self.record_ticket.ids) attachments = self.env['ir.attachment'].create(self.test_attachments_vals) - with self.assertQueryCount(employee=90): # test_mail_full: 88 + with self.assertQueryCount(employee=95): # test_mail_full: 88 new_message = record_ticket.message_post( attachment_ids=attachments.ids, body=Markup('

Test Content

'), diff --git a/addons/test_mail_full/tests/test_rating.py b/addons/test_mail_full/tests/test_rating.py index 35b870bb4d2..223a5d3514f 100644 --- a/addons/test_mail_full/tests/test_rating.py +++ b/addons/test_mail_full/tests/test_rating.py @@ -172,7 +172,7 @@ class TestRatingPerformance(TestRatingCommon): @users('employee') @warmup def test_rating_last_value_perfs(self): - with self.assertQueryCount(employee=1413): # tmf 1313 / com 1313 + with self.assertQueryCount(employee=1614): # tmf 1313 / com 1313 self.create_ratings('mail.test.rating.thread') with self.assertQueryCount(employee=2001): # tmf 1901 @@ -184,7 +184,7 @@ class TestRatingPerformance(TestRatingCommon): @users('employee') @warmup def test_rating_last_value_perfs_with_rating_mixin(self): - with self.assertQueryCount(employee=1519): # tmf 1419 / com 1419 + with self.assertQueryCount(employee=1721): # tmf 1419 / com 1419 self.create_ratings('mail.test.rating') with self.assertQueryCount(employee=2204): # tmf 2104 diff --git a/addons/test_mail_sms/tests/test_sms_performance.py b/addons/test_mail_sms/tests/test_sms_performance.py index ef53bb57c7b..0e92c7827d6 100644 --- a/addons/test_mail_sms/tests/test_sms_performance.py +++ b/addons/test_mail_sms/tests/test_sms_performance.py @@ -35,7 +35,7 @@ class TestSMSPerformance(BaseMailPerformance, sms_common.SMSCase): def test_message_sms_record_1_partner(self): record = self.test_record.with_user(self.env.user) pids = self.customer.ids - with self.mockSMSGateway(sms_allow_unlink=True), self.assertQueryCount(employee=25): + with self.mockSMSGateway(sms_allow_unlink=True), self.assertQueryCount(employee=26): messages = record._message_sms( body='Performance Test', partner_ids=pids, @@ -50,7 +50,7 @@ class TestSMSPerformance(BaseMailPerformance, sms_common.SMSCase): def test_message_sms_record_10_partners(self): record = self.test_record.with_user(self.env.user) pids = self.partners.ids - with self.mockSMSGateway(sms_allow_unlink=True), self.assertQueryCount(employee=25): + with self.mockSMSGateway(sms_allow_unlink=True), self.assertQueryCount(employee=26): messages = record._message_sms( body='Performance Test', partner_ids=pids, @@ -64,7 +64,7 @@ class TestSMSPerformance(BaseMailPerformance, sms_common.SMSCase): @warmup def test_message_sms_record_default(self): record = self.test_record.with_user(self.env.user) - with self.mockSMSGateway(sms_allow_unlink=True), self.assertQueryCount(employee=27): + with self.mockSMSGateway(sms_allow_unlink=True), self.assertQueryCount(employee=28): messages = record._message_sms( body='Performance Test', ) diff --git a/addons/website_sale/models/product_template.py b/addons/website_sale/models/product_template.py index 704255d230e..0098a9aa9d1 100644 --- a/addons/website_sale/models/product_template.py +++ b/addons/website_sale/models/product_template.py @@ -7,7 +7,6 @@ from odoo.addons.http_routing.models.ir_http import slug, unslug from odoo.addons.website.models import ir_http from odoo.tools.translate import html_translate from odoo.osv import expression -from psycopg2.extras import execute_values _logger = logging.getLogger(__name__) @@ -373,7 +372,7 @@ class ProductTemplate(models.Model): WHERE id = p.p_id """.format(table=self._table) values_args = [(prod_tmpl['id'], max_seq + i * 5) for i, prod_tmpl in enumerate(prod_tmpl_ids)] - execute_values(self.env.cr._obj, query, values_args) + self.env.cr.execute_values(query, values_args) else: super(ProductTemplate, self)._init_column(column_name) diff --git a/odoo/addons/base/models/ir_model.py b/odoo/addons/base/models/ir_model.py index 9a28e687ab7..21a214238cc 100644 --- a/odoo/addons/base/models/ir_model.py +++ b/odoo/addons/base/models/ir_model.py @@ -11,7 +11,7 @@ from collections.abc import Mapping from operator import itemgetter from psycopg2 import sql -from psycopg2.extras import Json, execute_values +from psycopg2.extras import Json from psycopg2.sql import Identifier, SQL, Placeholder from odoo import api, fields, models, tools, _, _lt, Command @@ -84,7 +84,7 @@ def query_insert(cr, table, rows): cols=SQL(",").join(map(Identifier, cols)), ) params = [tuple(row[col] for col in cols) for row in rows] - execute_values(cr._obj, query, params) + cr.execute_values(query, params) return [row[0] for row in cr.fetchall()] diff --git a/odoo/addons/test_performance/tests/test_performance.py b/odoo/addons/test_performance/tests/test_performance.py index 917ab833178..14b8a9221de 100644 --- a/odoo/addons/test_performance/tests/test_performance.py +++ b/odoo/addons/test_performance/tests/test_performance.py @@ -383,12 +383,12 @@ class TestPerformance(SavepointCaseWithUserDemo): rec1 = self.env['test_performance.base'].create({'name': 'X'}) # create N tags on rec1: O(1) queries - with self.assertQueryCount(3): + with self.assertQueryCount(4): self.env.invalidate_all() rec1.write({'tag_ids': [Command.create({'name': 0})]}) self.assertEqual(len(rec1.tag_ids), 1) - with self.assertQueryCount(3): + with self.assertQueryCount(4): self.env.invalidate_all() rec1.write({'tag_ids': [Command.create({'name': val}) for val in range(1, 12)]}) self.assertEqual(len(rec1.tag_ids), 12) @@ -436,12 +436,12 @@ class TestPerformance(SavepointCaseWithUserDemo): rec2 = self.env['test_performance.base'].create({'name': 'X'}) # link N tags from rec1 to rec2: O(1) queries - with self.assertQueryCount(2): + with self.assertQueryCount(3): self.env.invalidate_all() rec2.write({'tag_ids': [Command.link(tag.id) for tag in tags[0]]}) self.assertEqual(rec2.tag_ids, tags[0]) - with self.assertQueryCount(2): + with self.assertQueryCount(3): self.env.invalidate_all() rec2.write({'tag_ids': [Command.link(tag.id) for tag in tags[1:]]}) self.assertEqual(rec2.tag_ids, tags) @@ -464,7 +464,7 @@ class TestPerformance(SavepointCaseWithUserDemo): self.assertFalse(rec2.tag_ids) # set N tags in rec2: O(1) queries - with self.assertQueryCount(2): + with self.assertQueryCount(3): self.env.invalidate_all() rec2.write({'tag_ids': [Command.set(tags.ids)]}) self.assertEqual(rec2.tag_ids, tags) @@ -474,12 +474,12 @@ class TestPerformance(SavepointCaseWithUserDemo): rec2.write({'tag_ids': [Command.set(tags[:8].ids)]}) self.assertEqual(rec2.tag_ids, tags[:8]) - with self.assertQueryCount(3): + with self.assertQueryCount(4): self.env.invalidate_all() rec2.write({'tag_ids': [Command.set(tags[4:].ids)]}) self.assertEqual(rec2.tag_ids, tags[4:]) - with self.assertQueryCount(2): + with self.assertQueryCount(3): self.env.invalidate_all() rec2.write({'tag_ids': [Command.set(tags.ids)]}) self.assertEqual(rec2.tag_ids, tags) @@ -514,7 +514,7 @@ class TestPerformance(SavepointCaseWithUserDemo): self.env['test_performance.base'].create({'name': 'X'}) # create N tags: add O(1) queries - with self.assertQueryCount(3): + with self.assertQueryCount(4): self.env['test_performance.base'].create({ 'name': 'X', 'tag_ids': [Command.create({'name': val}) for val in range(10)], @@ -523,7 +523,7 @@ class TestPerformance(SavepointCaseWithUserDemo): # link N tags: add O(1) queries tags = self.env['test_performance.tag'].create([{'name': val} for val in range(10)]) - with self.assertQueryCount(2): + with self.assertQueryCount(3): self.env['test_performance.base'].create({ 'name': 'X', 'tag_ids': [Command.link(tag.id) for tag in tags], @@ -535,7 +535,7 @@ class TestPerformance(SavepointCaseWithUserDemo): 'tag_ids': [Command.set([])], }) - with self.assertQueryCount(2): + with self.assertQueryCount(3): self.env['test_performance.base'].create({ 'name': 'X', 'tag_ids': [Command.set(tags.ids)], diff --git a/odoo/fields.py b/odoo/fields.py index 1d95386fe10..5e920379b48 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -23,7 +23,7 @@ import warnings import psycopg2 import pytz from markupsafe import Markup -from psycopg2.extras import Json as PsycopgJson, execute_values +from psycopg2.extras import Json as PsycopgJson from psycopg2.sql import SQL, Identifier from difflib import get_close_matches, unified_diff from hashlib import sha256 @@ -4871,7 +4871,7 @@ class Many2many(_RelationalMulti): Identifier(self.column1), Identifier(self.column2), ) - execute_values(cr._obj, query, pairs) + cr.execute_values(query, pairs) # update the cache of inverse fields y_to_xs = defaultdict(set) diff --git a/odoo/sql_db.py b/odoo/sql_db.py index 3a8929391c5..5ada64eab5f 100644 --- a/odoo/sql_db.py +++ b/odoo/sql_db.py @@ -23,7 +23,7 @@ import psycopg2.extensions import psycopg2.extras from psycopg2.extensions import ISOLATION_LEVEL_REPEATABLE_READ from psycopg2.pool import PoolError -from psycopg2.sql import SQL, Identifier +from psycopg2.sql import SQL, Identifier, Composable from werkzeug import urls import odoo @@ -360,6 +360,17 @@ class Cursor(BaseCursor): self.sql_from_log[res_from.group(1)][1] += delay return res + def execute_values(self, query, argslist, template=None, page_size=100, fetch=False): + """ + A proxy for psycopg2.extras.execute_values which can log all queries like execute. + But this method cannot set log_exceptions=False like execute + """ + # Odoo Cursor only proxies all methods of psycopg2 Cursor. This is a patch for problems caused by passing + # self instead of self._obj to the first parameter of psycopg2.extras.execute_values. + if isinstance(query, Composable): + query = query.as_string(self._obj) + return psycopg2.extras.execute_values(self, query, argslist, template=template, page_size=page_size, fetch=fetch) + def split_for_in_conditions(self, ids, size=None): """Split a list of identifiers into one or more smaller tuples safe for IN conditions, after uniquifying them."""