Deprecate reduce_ids for SQL_OPERATORS['in']

Closes #12989 #13897
This commit is contained in:
Cédric Krier
2025-12-26 10:57:44 +01:00
parent 7b231e74e9
commit 0da67bce21
46 changed files with 191 additions and 234 deletions
+18 -11
View File
@@ -22,8 +22,8 @@ from trytond.pool import Pool
from trytond.pyson import Bool, Eval, Id, If, PYSONEncoder
from trytond.report import Report
from trytond.tools import (
grouped_slice, is_full_text, lstrip_wildcard, pair, reduce_ids,
sql_pairing, sqlite_apply_types)
grouped_slice, is_full_text, lstrip_wildcard, pair, sql_pairing,
sqlite_apply_types)
from trytond.transaction import Transaction, check_access, inactive_records
from trytond.wizard import (
Button, StateAction, StateTransition, StateView, Wizard)
@@ -1019,7 +1019,7 @@ class Account(
with transaction.set_context(company=company.id):
line_query, fiscalyear_ids = MoveLine.query_get(line)
for sub_ids in grouped_slice(ids):
red_sql = reduce_ids(table_a.id, sub_ids)
red_sql = fields.SQL_OPERATORS['in'](table_a.id, sub_ids)
if context.get('flat_balance'):
query = (table_a
.join(line, condition=line.account == table_a.id))
@@ -1092,7 +1092,7 @@ class Account(
Sum(Coalesce(Column(line, name), 0)).as_(name))
types.append('NUMERIC')
for sub_ids in grouped_slice(ids):
red_sql = reduce_ids(table.id, sub_ids)
red_sql = fields.SQL_OPERATORS['in'](table.id, sub_ids)
query = (table.join(line, 'LEFT',
condition=line.account == table.id
).select(*columns,
@@ -1531,9 +1531,11 @@ class AccountParty(ActivePeriodMixin, ModelSQL):
with transaction.set_context(company=company.id):
line_query, fiscalyear_ids = MoveLine.query_get(line)
for sub_account_ids in grouped_slice(account_ids):
account_sql = reduce_ids(table_a.id, sub_account_ids)
account_sql = fields.SQL_OPERATORS['in'](
table_a.id, sub_account_ids)
for sub_party_ids in grouped_slice(party_ids):
party_sql = reduce_ids(line.party, sub_party_ids)
party_sql = fields.SQL_OPERATORS['in'](
line.party, sub_party_ids)
if context.get('flat_balance'):
query = (table_a
.join(line, condition=line.account == table_a.id))
@@ -1608,9 +1610,11 @@ class AccountParty(ActivePeriodMixin, ModelSQL):
line_query, fiscalyear_ids = MoveLine.query_get(line)
for sub_account_ids in grouped_slice(account_ids):
account_sql = reduce_ids(table.id, sub_account_ids)
account_sql = fields.SQL_OPERATORS['in'](
table.id, sub_account_ids)
for sub_party_ids in grouped_slice(party_ids):
party_sql = reduce_ids(line.party, sub_party_ids)
party_sql = fields.SQL_OPERATORS['in'](
line.party, sub_party_ids)
query = (table.join(line, 'LEFT',
condition=line.account == table.id
).select(*columns,
@@ -1750,7 +1754,8 @@ class AccountDeferral(ModelSQL, ModelView):
balances = defaultdict(Decimal)
for sub_deferrals in grouped_slice(deferrals):
red_sql = reduce_ids(table.id, [d.id for d in sub_deferrals])
red_sql = fields.SQL_OPERATORS['in'](
table.id, [d.id for d in sub_deferrals])
query = (table
.join(account, condition=table.account == account.id)
.join(account_child,
@@ -2487,10 +2492,12 @@ class GeneralLedgerLine(DescriptionOriginMixin, ModelSQL, ModelView):
query = account_party.select(
account_party.account, account_party.party, account_party.id)
for sub_account_ids in grouped_slice(account_ids):
account_where = reduce_ids(account_party.account, sub_account_ids)
account_where = fields.SQL_OPERATORS['in'](
account_party.account, sub_account_ids)
for sub_party_ids in grouped_slice(party_ids):
query.where = (account_where
& reduce_ids(account_party.party, sub_party_ids))
& fields.SQL_OPERATORS['in'](
account_party.party, sub_party_ids))
cursor.execute(*query)
for account, party, id_ in cursor:
key = (account, party)
+3 -2
View File
@@ -12,7 +12,7 @@ from trytond.model import fields
from trytond.model.exceptions import AccessError
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool, PoolMeta
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.tools import grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction
@@ -67,7 +67,8 @@ class Company(metaclass=PoolMeta):
today_where = Literal(True)
for sub_companies in grouped_slice(companies):
sub_ids = [p.id for p in sub_companies]
company_where = reduce_ids(account.company, sub_ids)
company_where = fields.SQL_OPERATORS['in'](
account.company, sub_ids)
query = (line
.join(account,
condition=account.id == line.account)
+3 -3
View File
@@ -14,8 +14,7 @@ from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.tools import (
grouped_slice, is_full_text, lstrip_wildcard, reduce_ids,
sqlite_apply_types)
grouped_slice, is_full_text, lstrip_wildcard, sqlite_apply_types)
from trytond.transaction import Transaction
STATES = {
@@ -115,7 +114,8 @@ class Journal(
& (move.company == company.id))
for sub_journals in grouped_slice(journals):
sub_journals = list(sub_journals)
red_sql = reduce_ids(move.journal, [j.id for j in sub_journals])
red_sql = fields.SQL_OPERATORS['in'](
move.journal, [j.id for j in sub_journals])
query = line.join(move, 'LEFT', condition=line.move == move.id
).join(account, 'LEFT', condition=line.account == account.id
).join(account_type, 'LEFT',
+13 -8
View File
@@ -21,8 +21,7 @@ from trytond.pool import Pool
from trytond.pyson import Bool, Eval, If, PYSONEncoder
from trytond.report import Report
from trytond.rpc import RPC
from trytond.tools import (
firstline, grouped_slice, reduce_ids, sqlite_apply_types)
from trytond.tools import firstline, grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction, check_access
from trytond.wizard import (
Button, StateAction, StateTransition, StateView, Wizard)
@@ -363,7 +362,8 @@ class Move(DescriptionOriginMixin, ModelSQL, ModelView):
for company, moves in groupby(moves, key=lambda m: m.company):
currency = company.currency
for sub_moves in grouped_slice(list(moves)):
red_sql = reduce_ids(line.move, [m.id for m in sub_moves])
red_sql = fields.SQL_OPERATORS['in'](
line.move, [m.id for m in sub_moves])
valid_move_query = line.select(
line.move,
@@ -465,7 +465,8 @@ class Move(DescriptionOriginMixin, ModelSQL, ModelView):
cursor.execute(*move.select(
move.id,
where=reduce_ids(move.id, sub_moves_ids)
where=fields.SQL_OPERATORS['in'](
move.id, sub_moves_ids)
& ~Exists(line.select(
line.move,
where=line.move == move.id))))
@@ -480,7 +481,8 @@ class Move(DescriptionOriginMixin, ModelSQL, ModelView):
cursor.execute(*line.select(
line.move,
where=reduce_ids(line.move, sub_moves_ids),
where=fields.SQL_OPERATORS['in'](
line.move, sub_moves_ids),
group_by=line.move,
having=Abs(Round(
Sum(line.debit - line.credit),
@@ -496,7 +498,8 @@ class Move(DescriptionOriginMixin, ModelSQL, ModelView):
cursor.execute(*line.select(
line.id,
where=reduce_ids(line.move, sub_moves_ids)
where=fields.SQL_OPERATORS['in'](
line.move, sub_moves_ids)
& (line.debit == Decimal(0))
& (line.credit == Decimal(0))
& (line.reconciliation == Null)
@@ -864,7 +867,8 @@ class MoveLineMixin:
parties = {l.party for l in sub_lines}
if None in parties:
party_where |= line.party == parties.discard(None)
party_where |= reduce_ids(line.party, map(int, parties))
party_where |= fields.SQL_OPERATORS['in'](
line.party, map(int, parties))
where &= party_where
query = (line
@@ -878,7 +882,8 @@ class MoveLineMixin:
where=where))
query = query.select(
query.id, query.balance.as_('balance'),
where=reduce_ids(query.id, [l.id for l in sub_lines]))
where=fields.SQL_OPERATORS['in'](
query.id, [l.id for l in sub_lines]))
if backend.name == 'sqlite':
sqlite_apply_types(query, [None, 'NUMERIC'])
cursor.execute(*query)
+3 -2
View File
@@ -16,7 +16,7 @@ from trytond.modules.currency.fields import Monetary
from trytond.modules.party.exceptions import EraseError
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, If
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.tools import grouped_slice, sqlite_apply_types
from trytond.tools import timezone as tz
from trytond.transaction import Transaction
@@ -165,7 +165,8 @@ class Party(CompanyMultiValueMixin, metaclass=PoolMeta):
columns.append(Coalesce(expressions[name], Decimal()).as_(name))
if parties is not None:
party_where = reduce_ids(move_line.party, [p.id for p in parties])
party_where = fields.SQL_OPERATORS['in'](
move_line.party, [p.id for p in parties])
else:
party_where = Literal(True)
+6 -5
View File
@@ -17,7 +17,7 @@ from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Bool, Eval, If
from trytond.rpc import RPC
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.tools import grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction
from trytond.wizard import (
Button, StateAction, StateTransition, StateView, Wizard)
@@ -213,7 +213,7 @@ class BudgetLineMixin(
sqlite_apply_types(query, [None, 'NUMERIC'])
for sub_ids in grouped_slice(ids):
query.where = reduce_ids(table.id, sub_ids)
query.where = fields.SQL_OPERATORS['in'](table.id, sub_ids)
cursor.execute(*query)
amounts.update(cursor)
@@ -549,7 +549,7 @@ class BudgetLine(BudgetLineMixin, ModelSQL, ModelView):
line = Line.__table__()
amount = Sum(Coalesce(line.credit, 0) - Coalesce(line.debit, 0))
red_sql = reduce_ids(table.id, [r.id for r in records])
red_sql = fields.SQL_OPERATORS['in'](table.id, [r.id for r in records])
periods = Transaction().context.get('periods')
if not periods:
periods = [p.id for p in Period.search([
@@ -693,7 +693,7 @@ class BudgetLinePeriod(AmountMixin, ModelSQL, ModelView):
line = MoveLine.__table__()
amount = Sum(Coalesce(line.credit, 0) - Coalesce(line.debit, 0))
red_sql = reduce_ids(table.id, [r.id for r in records])
red_sql = fields.SQL_OPERATORS['in'](table.id, [r.id for r in records])
periods = Transaction().context.get('periods')
if not periods:
periods = [p.id for p in Period.search([
@@ -737,7 +737,8 @@ class BudgetLinePeriod(AmountMixin, ModelSQL, ModelView):
for sub_ids in grouped_slice({p.budget_line.id for p in periods}):
cursor.execute(*table.select(
table.budget_line,
where=reduce_ids(table.budget_line, sub_ids),
where=fields.SQL_OPERATORS['in'](
table.budget_line, sub_ids),
group_by=table.budget_line,
having=Sum(table.ratio) > 1,
limit=1))
+3 -2
View File
@@ -12,7 +12,7 @@ from trytond.model import fields
from trytond.modules.currency.fields import Monetary
from trytond.modules.party.exceptions import EraseError
from trytond.pool import Pool, PoolMeta
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.tools import grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction
@@ -46,7 +46,8 @@ class Party(metaclass=PoolMeta):
line_clause, _ = MoveLine.query_get(line)
for sub_parties in grouped_slice(parties):
party_clause = reduce_ids(line.party, [p.id for p in sub_parties])
party_clause = fields.SQL_OPERATORS['in'](
line.party, [p.id for p in sub_parties])
query = (line
.join(account, condition=account.id == line.account)
.join(account_type, condition=account.type == account_type.id)
+7 -6
View File
@@ -32,8 +32,7 @@ from trytond.pyson import Bool, Eval, Id, If
from trytond.report import Report
from trytond.rpc import RPC
from trytond.tools import (
cached_property, firstline, grouped_slice, reduce_ids, slugify,
sqlite_apply_types)
cached_property, firstline, grouped_slice, slugify, sqlite_apply_types)
from trytond.transaction import Transaction
from trytond.wizard import (
Button, StateAction, StateReport, StateTransition, StateView, Wizard)
@@ -829,8 +828,9 @@ class Invoice(
type_name = cls.tax_amount._field.sql_type().base
tax = InvoiceTax.__table__()
for sub_ids in grouped_slice(invoices_no_cache):
red_sql = reduce_ids(tax.invoice, sub_ids)
for sub_invoices in grouped_slice(invoices_no_cache):
red_sql = fields.SQL_OPERATORS['in'](
tax.invoice, map(int, sub_invoices))
query = (tax.select(tax.invoice,
Coalesce(Sum(tax.amount), 0).as_(type_name),
where=red_sql,
@@ -885,7 +885,8 @@ class Invoice(
invoice = cls.__table__()
additional_move = AdditionalMove.__table__()
red_sql = reduce_ids(invoice.id, invoices)
red_sql = fields.SQL_OPERATORS['in'](
invoice.id, map(int, invoices))
query = (invoice
.join(line,
condition=((invoice.move == line.move)
@@ -1152,7 +1153,7 @@ class Invoice(
for sub_invoices in grouped_slice(invoices):
sub_ids = map(int, sub_invoices)
cursor.execute(*table.select(table.id, has_cache,
where=reduce_ids(table.id, sub_ids)))
where=fields.SQL_OPERATORS['in'](table.id, sub_ids)))
result.update(cursor)
return result
+2 -2
View File
@@ -7,7 +7,7 @@ from sql.functions import CurrentTimestamp
from trytond import backend
from trytond.model import ModelView, Workflow, fields
from trytond.pool import Pool, PoolMeta
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.tools import grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction
@@ -55,7 +55,7 @@ class Invoice(metaclass=PoolMeta):
Greatest(table.numbered_at, party.create_date,
address.create_date, identifier.create_date,
payment_term.create_date).as_('history_datetime'),
where=reduce_ids(table.id, ids)
where=fields.SQL_OPERATORS['in'](table.id, ids)
& (table.numbered_at != Null)
& (table.state.in_(cls._history_states()))))
if backend.name == 'sqlite':
+3 -2
View File
@@ -19,7 +19,7 @@ from trytond.modules.company.model import CompanyValueMixin
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, Id, If
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction, check_access, without_check_access
from trytond.wizard import (
Button, StateAction, StateTransition, StateView, Wizard)
@@ -195,7 +195,8 @@ class MoveLine(metaclass=PoolMeta):
for sub_lines in grouped_slice(lines):
query.where = (
table.account.in_(accounts)
& reduce_ids(table.id, map(int, sub_lines)))
& fields.SQL_OPERATORS['in'](
table.id, map(int, sub_lines)))
cursor.execute(*query)
else:
cursor.execute(*query)
+4 -4
View File
@@ -22,8 +22,7 @@ from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, If
from trytond.rpc import RPC
from trytond.tools import (
cursor_dict, grouped_slice, reduce_ids, sortable_values,
sqlite_apply_types)
cursor_dict, grouped_slice, sortable_values, sqlite_apply_types)
from trytond.transaction import Transaction
from trytond.wizard import StateAction, Wizard
@@ -202,9 +201,10 @@ class Group(ModelSQL, ModelView, ChatMixin):
).as_('payment_not_complete'),
]
for sub_ids in grouped_slice(groups):
for sub_groups in grouped_slice(groups):
query = payment.select(*columns,
where=reduce_ids(payment.group, sub_ids),
where=fields.SQL_OPERATORS['in'](
payment.group, map(int, sub_groups)),
group_by=payment.group)
if backend.name == 'sqlite':
sqlite_apply_types(
+3 -2
View File
@@ -13,7 +13,7 @@ from trytond.model import ModelView, Workflow, fields
from trytond.modules.account.exceptions import AccountMissing
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, If, TimeDelta
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
from trytond.wizard import Button, StateTransition, StateView, Wizard
@@ -447,7 +447,8 @@ class Group(metaclass=PoolMeta):
for sub_groups in grouped_slice(groups):
cursor.execute(*payment.select(
payment.group, column,
where=reduce_ids(payment.group, sub_groups),
where=fields.SQL_OPERATORS['in'](
payment.group, map(int, sub_groups)),
group_by=payment.group))
result.update(cursor)
return result
+7 -5
View File
@@ -26,7 +26,7 @@ from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, If
from trytond.report import Report
from trytond.tools import (
cached_property, grouped_slice, is_full_text, lstrip_wildcard, reduce_ids,
cached_property, grouped_slice, is_full_text, lstrip_wildcard,
sortable_values)
from trytond.transaction import Transaction
@@ -786,8 +786,9 @@ class Mandate(Workflow, ModelSQL, ModelView):
cursor = Transaction().connection.cursor()
has_payments = dict.fromkeys([m.id for m in mandates], False)
for sub_ids in grouped_slice(mandates):
red_sql = reduce_ids(payment.sepa_mandate, sub_ids)
for sub_mandates in grouped_slice(mandates):
red_sql = fields.SQL_OPERATORS['in'](
payment.sepa_mandate, map(int, sub_mandates))
cursor.execute(*payment.select(payment.sepa_mandate, Literal(True),
where=red_sql,
group_by=payment.sepa_mandate))
@@ -803,8 +804,9 @@ class Mandate(Workflow, ModelSQL, ModelView):
cursor = Transaction().connection.cursor()
is_first = dict.fromkeys([m.id for m in mandates], True)
for sub_ids in grouped_slice(mandates):
red_sql = reduce_ids(payment.sepa_mandate, sub_ids)
for sub_mandates in grouped_slice(mandates):
red_sql = fields.SQL_OPERATORS['in'](
payment.sepa_mandate, map(int, sub_mandates))
cursor.execute(*payment.select(
payment.sepa_mandate, Literal(False),
where=red_sql
+5 -5
View File
@@ -10,8 +10,7 @@ from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.rpc import RPC
from trytond.tools import (
cursor_dict, grouped_slice, reduce_ids, sqlite_apply_types)
from trytond.tools import cursor_dict, grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction
@@ -145,9 +144,10 @@ class Journal(DeactivableMixin, ModelSQL, ModelView):
columns.append(
FirstValue(statement.date, window=w).as_('last_date'))
query = statement.select(*columns,
distinct=True,
where=reduce_ids(statement.journal, sub_ids)
& (statement.state != 'cancelled'))
distinct=True,
where=(fields.SQL_OPERATORS['in'](
statement.journal, sub_ids)
& (statement.state != 'cancelled')))
if backend.name == 'sqlite':
types = [None]
if 'last_amount' in names:
+1 -2
View File
@@ -8,7 +8,6 @@ from trytond.modules.account_budget import (
BudgetLineMixin, BudgetMixin, CopyBudgetMixin, CopyBudgetStartMixin)
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.tools import reduce_ids
from trytond.transaction import Transaction
from trytond.wizard import Button, StateAction, StateView, Wizard
@@ -179,7 +178,7 @@ class BudgetLine(BudgetLineMixin, ModelSQL, ModelView):
children = cls.__table__()
balance = Sum(Coalesce(line.credit, 0) - Coalesce(line.debit, 0))
red_sql = reduce_ids(table.id, [r.id for r in records])
red_sql = fields.SQL_OPERATORS['in'](table.id, [r.id for r in records])
with Transaction().set_context(context):
query_where = Line.query_get(line)
return (table
+2 -3
View File
@@ -21,8 +21,7 @@ from trytond.modules.currency.fields import Monetary
from trytond.modules.product import price_digits, round_price
from trytond.pool import Pool
from trytond.pyson import Bool, Eval, Id, If
from trytond.tools import (
decistmt, grouped_slice, reduce_ids, sqlite_apply_types)
from trytond.tools import decistmt, grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction, check_access
from trytond.wizard import Button, StateAction, StateView, Wizard
@@ -129,7 +128,7 @@ class Agent(DeactivableMixin, ModelSQL, ModelView):
ids = [a.id for a in agents]
amounts = dict.fromkeys(ids, None)
for sub_ids in grouped_slice(ids):
where = reduce_ids(commission.agent, sub_ids)
where = fields.SQL_OPERATORS['in'](commission.agent, sub_ids)
where &= commission.invoice_line == Null
query = commission.select(
commission.agent, Sum(commission.amount).as_('pending_amount'),
@@ -26,7 +26,7 @@ from trytond.pool import Pool
from trytond.pyson import Eval, If, PYSONDecoder, TimeDelta
from trytond.report import Report, html_to_text, mjml_to_html
from trytond.sendmail import SMTPDataManager, send_message_transactional
from trytond.tools import grouped_slice, pairwise_longest, reduce_ids
from trytond.tools import grouped_slice, pairwise_longest
from trytond.tools.chart import sparkline
from trytond.tools.email_ import format_address, has_rcpt, set_from_header
from trytond.transaction import Transaction
@@ -178,12 +178,13 @@ class Scenario(
others.append(scenario)
count = {name: defaultdict(int) for name in names}
for sub in grouped_slice(others):
for sub_others in grouped_slice(others):
cursor.execute(*record.select(
record.scenario,
Count(),
Count(filter_=record.blocked),
where=reduce_ids(record.scenario, sub),
where=fields.SQL_OPERATORS['in'](
record.scenario, map(int, sub_others)),
group_by=record.scenario))
for id_, all_, blocked in cursor:
if 'record_count' in count:
@@ -521,13 +522,14 @@ class Activity(
cursor = Transaction().connection.cursor()
count = {name: defaultdict(int) for name in names}
for sub in grouped_slice(activities):
for sub_activities in grouped_slice(activities):
cursor.execute(*record_activity.select(
record_activity.activity,
Count(filter_=record_activity.state == 'done'),
Count(filter_=record_activity.email_opened),
Count(filter_=record_activity.email_clicked),
where=reduce_ids(record_activity.activity, sub),
where=fields.SQL_OPERATORS['in'](
record_activity.activity, map(int, sub_activities)),
group_by=record_activity.activity))
for id_, all_, email_opened, email_clicked in cursor:
if 'record_count' in count:
+3 -2
View File
@@ -22,7 +22,7 @@ from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.report import Report, get_email, html_to_text, mjml_to_html
from trytond.sendmail import SMTPDataManager, send_message_transactional
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.tools.email_ import (
EmailNotValidError, format_address, normalize_email, set_from_header,
validate_email)
@@ -259,7 +259,8 @@ class EmailList(DeactivableMixin, ModelSQL, ModelView):
email.list_, Count(), group_by=[email.list_])
for sub_lists in grouped_slice(lists):
query.where = (
reduce_ids(email.list_, sub_lists)
fields.SQL_OPERATORS['in'](
email.list_, map(int, sub_lists))
& email.active)
cursor.execute(*query)
subscribed.update(cursor)
+8 -7
View File
@@ -10,7 +10,7 @@ from trytond.cache import Cache, freeze
from trytond.model import ModelSQL, dualmethod, fields
from trytond.pool import Pool, PoolMeta
from trytond.protocols.jsonrpc import JSONDecoder, JSONEncoder
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
dumps = partial(
@@ -164,20 +164,21 @@ class PriceListCache(ModelSQL):
cursor.execute(*cache.delete())
elif price_lists and products is None:
for sub_price_lists in grouped_slice(price_lists):
cursor.execute(*cache.delete(where=reduce_ids(
cursor.execute(*cache.delete(where=fields.SQL_OPERATORS['in'](
cache.price_list, [
p.id for p in sub_price_lists])))
elif price_lists is None and products:
for sub_products in grouped_slice(products):
cursor.execute(*cache.delete(where=reduce_ids(
cursor.execute(*cache.delete(where=fields.SQL_OPERATORS['in'](
cache.product, [p.id for p in sub_products])))
else:
for sub_products in grouped_slice(products):
for sub_price_lists in grouped_slice(price_lists):
cursor.execute(*cache.delete(where=reduce_ids(
cache.price_list, [
p.id for p in sub_price_lists])
& reduce_ids(
cursor.execute(*cache.delete(
where=fields.SQL_OPERATORS['in'](
cache.price_list, [
p.id for p in sub_price_lists])
& fields.SQL_OPERATORS['in'](
cache.product, [p.id for p in sub_products])))
@classmethod
+3 -2
View File
@@ -19,7 +19,7 @@ from trytond.modules.company.model import employee_field, set_employee
from trytond.modules.product import price_digits, round_price
from trytond.pool import Pool
from trytond.pyson import Bool, Eval, If, TimeDelta
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.tools import grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction
from .exceptions import PickerError
@@ -250,7 +250,8 @@ class Work(sequence_ordered(), ModelSQL, ModelView, ChatMixin):
costs = defaultdict(Decimal)
for sub_works in grouped_slice(works):
red_sql = reduce_ids(cycle.work, [w.id for w in sub_works])
red_sql = fields.SQL_OPERATORS['in'](
cycle.work, [w.id for w in sub_works])
query = cycle.select(
cycle.work, Sum(Coalesce(cycle.cost, 0)).as_('cost'),
where=red_sql & (cycle.state == 'done'),
+2 -2
View File
@@ -10,7 +10,7 @@ from trytond.model import fields
from trytond.modules.account_invoice.exceptions import (
InvoiceLineValidationError)
from trytond.pool import Pool, PoolMeta
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
@@ -92,7 +92,7 @@ class InvoiceLine(metaclass=PoolMeta):
ts_line.invoice_line, Sum(ts_line.duration),
group_by=ts_line.invoice_line)
for sub_lines in grouped_slice(lines):
query.where = reduce_ids(
query.where = fields.SQL_OPERATORS['in'](
ts_line.invoice_line, map(int, sub_lines))
cursor.execute(*query)
+6 -5
View File
@@ -18,7 +18,7 @@ from trytond.model.exceptions import AccessError
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, Id, If
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.tools import grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction
from trytond.wizard import StateAction, Wizard
@@ -114,7 +114,7 @@ class Progress:
quantities = {}
for sub_works in grouped_slice(works):
sub_works = list(sub_works)
where = reduce_ids(
where = fields.SQL_OPERATORS['in'](
table.id, [x.id for x in sub_works if x.invoice_unit_price])
cursor.execute(*table.join(progress,
condition=progress.work == table.id
@@ -162,7 +162,7 @@ class Progress:
work2currency = {}
ids2work = dict((w.id, w) for w in works)
for sub_ids in grouped_slice(ids2work.keys()):
where = reduce_ids(table.id, sub_ids)
where = fields.SQL_OPERATORS['in'](table.id, sub_ids)
query = (table.join(progress,
condition=progress.work == table.id
).join(invoice_line,
@@ -275,7 +275,8 @@ class Timesheet:
group_by=line.work)
for upto, tworks in upto2tworks.items():
for sub_ids in grouped_slice(tworks):
query.where = (reduce_ids(line.work, sub_ids)
query.where = (
fields.SQL_OPERATORS['in'](line.work, sub_ids)
& (line.invoice_line == Null))
if upto:
query.where &= (line.date <= upto)
@@ -318,7 +319,7 @@ class Timesheet:
work2currency = {}
work_ids = [w.id for w in works]
for sub_ids in grouped_slice(work_ids):
where = reduce_ids(table.id, sub_ids)
where = fields.SQL_OPERATORS['in'](table.id, sub_ids)
cursor.execute(*table.join(timesheet_work,
condition=(
Concat(cls.__name__ + ',', table.id)
+4 -4
View File
@@ -13,7 +13,7 @@ from trytond.modules.currency.fields import Monetary
from trytond.modules.product import price_digits, round_price
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
@@ -95,13 +95,13 @@ class Work(metaclass=PoolMeta):
work_ids = [w.id for w in works]
for sub_ids in grouped_slice(work_ids):
red_sql = reduce_ids(table.id, sub_ids)
where = fields.SQL_OPERATORS['in'](table.id, sub_ids)
cursor.execute(*table.join(work,
condition=(
Concat(cls.__name__ + ',', table.id) == work.origin)
).join(line, condition=line.work == work.id
).select(table.id, Sum(line.cost_price * line.duration),
where=red_sql,
where=where,
group_by=[table.id]))
for work_id, cost in cursor:
# SQLite stores timedelta as float
@@ -135,7 +135,7 @@ class Work(metaclass=PoolMeta):
work2currency = {}
iline2work = {}
for sub_ids in grouped_slice(work_ids):
where = reduce_ids(table.id, sub_ids)
where = fields.SQL_OPERATORS['in'](table.id, sub_ids)
cursor.execute(*table.join(purchase_line,
condition=purchase_line.work == table.id
).join(invoice_line,
+2 -3
View File
@@ -13,8 +13,7 @@ from trytond.modules.product import (
ProductDeactivatableMixin, price_digits, round_price)
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, If, TimeDelta
from trytond.tools import (
grouped_slice, is_full_text, lstrip_wildcard, reduce_ids)
from trytond.tools import grouped_slice, is_full_text, lstrip_wildcard
from trytond.transaction import Transaction
from .exceptions import PurchaseUOMWarning
@@ -160,7 +159,7 @@ class Product(metaclass=PoolMeta):
.join(purchase, condition=line.purchase == purchase.id)
.select(
Max(line.id),
where=where & reduce_ids(
where=where & fields.SQL_OPERATORS['in'](
line.product, map(int, sub_products)),
group_by=[line.product]))
cursor.execute(*query)
+3 -2
View File
@@ -4,7 +4,7 @@
from trytond.model import ModelView, Workflow, fields
from trytond.pool import PoolMeta
from trytond.pyson import Eval
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
@@ -49,7 +49,8 @@ class Purchase(metaclass=PoolMeta):
cursor.execute(*table.update(
[table.revision],
[table.revision + 1],
where=reduce_ids(table.id, sub_purchases)))
where=fields.SQL_OPERATORS['in'](
table.id, map(int, sub_purchases))))
super().draft(purchases)
+5 -3
View File
@@ -15,7 +15,7 @@ from trytond.model import ModelSQL, ModelView, UnionMixin, fields, sum_tree
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Eval, If
from trytond.tools import grouped_slice, pairwise_longest, reduce_ids
from trytond.tools import grouped_slice, pairwise_longest
from trytond.tools.chart import sparkline
from trytond.transaction import Transaction
from trytond.wizard import StateAction, StateTransition, Wizard
@@ -517,7 +517,8 @@ class CustomerCategoryTree(ModelSQL, ModelView):
reporting_customer_categories = []
for sub_ids in grouped_slice(ids):
sub_ids = list(sub_ids)
where = reduce_ids(reporting_product_category.id, sub_ids)
where = fields.SQL_OPERATORS['in'](
reporting_product_category.id, sub_ids)
cursor.execute(
*reporting_product_category.select(
reporting_product_category.id, where=where))
@@ -758,7 +759,8 @@ class ProductCategoryTree(ModelSQL, ModelView):
reporting_product_categories = []
for sub_ids in grouped_slice(ids):
sub_ids = list(sub_ids)
where = reduce_ids(reporting_product_category.id, sub_ids)
where = fields.SQL_OPERATORS['in'](
reporting_product_category.id, sub_ids)
cursor.execute(
*reporting_product_category.select(
reporting_product_category.id, where=where))
+3 -2
View File
@@ -4,7 +4,7 @@
from trytond.model import ModelView, Workflow, fields
from trytond.pool import PoolMeta
from trytond.pyson import Eval
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
@@ -45,7 +45,8 @@ class RevisionMixin:
cursor.execute(*table.update(
[table.revision],
[table.revision + 1],
where=reduce_ids(table.id, sub_records)))
where=fields.SQL_OPERATORS['in'](
table.id, map(int, sub_records))))
super().draft(records)
+5 -3
View File
@@ -21,7 +21,7 @@ from trytond.modules.currency.fields import Monetary
from trytond.modules.product import price_digits, round_price
from trytond.pool import Pool
from trytond.pyson import Bool, Eval, Id, If
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.tools import grouped_slice, sqlite_apply_types
from trytond.transaction import Transaction
from trytond.wizard import Button, StateTransition, StateView, Wizard
@@ -865,12 +865,14 @@ class POSCashSession(Workflow, ModelSQL, ModelView):
payment.select(
payment.session.as_('session'),
Sum(payment.amount).as_('amount'),
where=reduce_ids(payment.session, sub_ids),
where=fields.SQL_OPERATORS['in'](
payment.session, sub_ids),
group_by=[payment.session]),
transfer.select(
transfer.session.as_('session'),
Sum(transfer.amount).as_('amount'),
where=reduce_ids(transfer.session, sub_ids),
where=fields.SQL_OPERATORS['in'](
transfer.session, sub_ids),
group_by=[transfer.session]),
all_=True)
query = query.select(
+3 -2
View File
@@ -15,7 +15,7 @@ from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval, If
from trytond.sql.functions import DateRange
from trytond.sql.operators import RangeOverlap
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
from .exceptions import PromotionCouponNumberDatesError
@@ -302,7 +302,8 @@ class PromotionCouponNumber(DeactivableMixin, ModelSQL, ModelView):
result = {}
for sub_numbers in grouped_slice(numbers):
query.where = reduce_ids(table.id, map(int, sub_numbers))
query.where = fields.SQL_OPERATORS['in'](
table.id, map(int, sub_numbers))
cursor.execute(*query)
result.update(dict(cursor))
return result
+6 -5
View File
@@ -19,7 +19,7 @@ from trytond.model.exceptions import AccessError
from trytond.modules.product import price_digits, round_price
from trytond.pool import Pool
from trytond.pyson import Bool, Eval, Id, If, TimeDelta
from trytond.tools import cached_property, grouped_slice, reduce_ids
from trytond.tools import cached_property, grouped_slice
from trytond.transaction import Transaction, without_check_access
from .exceptions import MoveFutureWarning, MoveOriginWarning
@@ -1331,9 +1331,9 @@ class Move(Workflow, ModelSQL, ModelView):
sub_location_ids = list(sub_location_ids)
table = cls.__table__()
query = table.select(Literal(1),
where=(reduce_ids(
where=(fields.SQL_OPERATORS['in'](
table.to_location, sub_location_ids)
| reduce_ids(
| fields.SQL_OPERATORS['in'](
table.from_location, sub_location_ids))
& table.product.in_(product_ids)
& (table.company == company_id),
@@ -1635,9 +1635,10 @@ class Move(Workflow, ModelSQL, ModelView):
if PeriodCache:
cache_column = Column(period_cache, fieldname)
if isinstance(grouping_ids[0], (int, float, Decimal)):
where &= reduce_ids(column, grouping_ids)
where &= fields.SQL_OPERATORS['in'](column, grouping_ids)
if PeriodCache:
where_period &= reduce_ids(cache_column, grouping_ids)
where_period &= fields.SQL_OPERATORS['in'](
cache_column, grouping_ids)
else:
where &= column.in_(grouping_ids)
if PeriodCache:
+9 -5
View File
@@ -17,7 +17,7 @@ from trytond.model.exceptions import AccessError
from trytond.modules.product import price_digits, round_price
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, If, PYSONEncoder
from trytond.tools import decistmt, grouped_slice, reduce_ids
from trytond.tools import decistmt, grouped_slice
from trytond.tools import timezone as tz
from trytond.transaction import Transaction, without_check_access
from trytond.wizard import (
@@ -679,7 +679,8 @@ class ProductQuantitiesByWarehouse(ModelSQL, ModelView):
raise AccessError(gettext(
'stock.msg_product_quantities_max',
max=transaction.database.IN_MAX))
product_clause = reduce_ids(product.template, product_template)
product_clause = fields.SQL_OPERATORS['in'](
product.template, product_template)
else:
product_clause = product.template == Null
product_column = Concat('product.template,', product.template)
@@ -695,7 +696,8 @@ class ProductQuantitiesByWarehouse(ModelSQL, ModelView):
raise AccessError(gettext(
'stock.msg_product_quantities_max',
max=transaction.database.IN_MAX))
product_clause = reduce_ids(move.product, product)
product_clause = fields.SQL_OPERATORS['in'](
move.product, product)
else:
product_clause = move.product == Null
product_column = Concat('product.product,', move.product)
@@ -945,7 +947,8 @@ class ProductQuantitiesByWarehouseMove(ModelSQL, ModelView):
raise AccessError(gettext(
'stock.msg_product_quantities_max',
max=transaction.database.IN_MAX))
product_clause = reduce_ids(product.template, product_template)
product_clause = fields.SQL_OPERATORS['in'](
product.template, product_template)
else:
product_clause = product.template == Null
product_column = Concat('product.template,', product.template)
@@ -960,7 +963,8 @@ class ProductQuantitiesByWarehouseMove(ModelSQL, ModelView):
raise AccessError(gettext(
'stock.msg_product_quantities_max',
max=transaction.database.IN_MAX))
product_clause = reduce_ids(move.product, product)
product_clause = fields.SQL_OPERATORS['in'](
move.product, product)
else:
product_clause = move.product == Null
product_column = Concat('product.product,', move.product)
+3 -2
View File
@@ -15,7 +15,7 @@ from trytond.model import ModelSQL, ModelView, fields, sum_tree
from trytond.modules.currency.fields import Monetary
from trytond.pool import Pool
from trytond.pyson import Eval, If
from trytond.tools import grouped_slice, pairwise_longest, reduce_ids
from trytond.tools import grouped_slice, pairwise_longest
from trytond.tools.chart import sparkline
from trytond.transaction import Transaction
@@ -596,7 +596,8 @@ class CategoryTree(ModelSQL, ModelView):
reporting_categories = []
for sub_ids in grouped_slice(ids):
sub_ids = list(sub_ids)
where = reduce_ids(reporting_category.id, sub_ids)
where = fields.SQL_OPERATORS['in'](
reporting_category.id, sub_ids)
cursor.execute(
*reporting_category.select(reporting_category.id, where=where))
reporting_categories.extend(r for r, in cursor)
+3 -3
View File
@@ -18,7 +18,7 @@ from trytond.pool import Pool
from trytond.pyson import Bool, Eval, If
from trytond.sql.functions import DateRange
from trytond.sql.operators import RangeOverlap
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
from trytond.wizard import Button, StateTransition, StateView, Wizard
@@ -357,13 +357,13 @@ class ForecastLine(ModelSQL, ModelView):
product2line = dict((line.product.id, line) for line in lines)
product_ids = product2line.keys()
for sub_ids in grouped_slice(product_ids):
red_sql = reduce_ids(move.product, sub_ids)
where = fields.SQL_OPERATORS['in'](move.product, sub_ids)
cursor.execute(*move.join(location_from,
condition=move.from_location == location_from.id
).join(location_to,
condition=move.to_location == location_to.id
).select(move.product, Sum(move.internal_quantity),
where=red_sql
where=where
& (location_from.left >= forecast.warehouse.left)
& (location_from.right <= forecast.warehouse.right)
& (location_to.left >= forecast.destination.left)
+1 -2
View File
@@ -249,12 +249,11 @@ class QuantityIssue(
issue.issue_products = []
issues[issue.origin] = issue
# Order by id to speedup reduce_ids
products = Product.search([
('type', 'in', ['goods', 'assets']),
('consumable', '=', False),
],
order=[('id', 'ASC')])
order=[])
for product in products:
for warehouse in warehouses:
+5 -3
View File
@@ -13,7 +13,7 @@ from trytond.model import Index, ModelSQL, ModelView, Workflow, fields
from trytond.modules.company.model import CompanyValueMixin
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Bool, Eval, Id
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
@@ -285,7 +285,9 @@ class MeasurementsMixin(object):
where = query.where
for sub_shipments in grouped_slice(shipments):
query.where = (
where & reduce_ids(table.id, map(int, sub_shipments)))
where
& fields.SQL_OPERATORS['in'](
table.id, map(int, sub_shipments)))
cursor.execute(*query)
else:
cursor.execute(*query)
@@ -331,7 +333,7 @@ class MeasurementsMixin(object):
if s.state not in states
or s.internal_weight is None
or s.internal_volume is None)):
query.where = reduce_ids(
query.where = fields.SQL_OPERATORS['in'](
table.id, [s.id for s in sub_shipments])
cursor.execute(*query)
for id_, weight, volume in cursor:
+2 -2
View File
@@ -65,12 +65,12 @@ class PurchaseRequest(metaclass=PoolMeta):
if products is None:
# fetch goods and assets
# ordered by ids to speedup reduce_ids in products_by_location
products = Product.search([
('type', 'in', ['goods', 'assets']),
('consumable', '=', False),
('purchasable', '=', True),
], order=[('id', 'ASC')])
],
order=[])
# aggregate product by minimum supply date
date2products = defaultdict(list)
for product in products:
+2 -2
View File
@@ -89,11 +89,11 @@ class ShipmentInternal(ModelSQL, ModelView):
location_ids, with_childs=True,
grouping_filter=grouping_filter)
# ordered by ids to speedup reduce_ids in products_by_location
if implicit_locations:
products = Product.search([
('type', 'in', ['goods', 'assets']),
], order=[('id', 'ASC')])
],
order=[])
product_ids = [p.id for p in products]
pbl = get_pbl(None, today, None)
else:
+3 -3
View File
@@ -10,7 +10,7 @@ from trytond.i18n import gettext
from trytond.model import ModelSQL, ModelStorage, ModelView, Unique, fields
from trytond.pool import Pool
from trytond.pyson import Bool, Eval, If
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
from .exceptions import CompanyValidationError
@@ -106,9 +106,9 @@ class Work(ModelSQL, ModelView):
condition=line.work == table_w.id)
for sub_ids in grouped_slice(ids):
red_sql = reduce_ids(table_w.id, sub_ids)
cursor.execute(*query_table.select(table_w.id, Sum(line.duration),
where=red_sql & where,
where=where
& fields.SQL_OPERATORS['in'](table_w.id, sub_ids),
group_by=table_w.id))
for work_id, duration in cursor:
# SQLite uses float for SUM
+2 -2
View File
@@ -10,7 +10,7 @@ from sql.aggregate import Count
import trytond.config as config
from trytond.model import ModelSQL, ModelView, fields
from trytond.pool import Pool
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
from trytond.url import http_host
from trytond.wsgi import Base64Converter
@@ -56,7 +56,7 @@ class ShortenedURL(ModelSQL, ModelView):
for sub_ids in grouped_slice(shortened_urls):
cursor.execute(*access.select(
access.url, Count(access.id),
where=reduce_ids(access.url, sub_ids),
where=fields.SQL_OPERATORS['in'](access.url, sub_ids),
group_by=[access.url]))
counts.update(cursor)
return counts
+1
View File
@@ -1,3 +1,4 @@
* Deprecate ``reduce_ids`` for ``SQL_OPERATORS['in']``
* Use array for ``in`` operators
* Update to Psycopg 3
* Add support for Python 3.14
+2 -2
View File
@@ -22,7 +22,7 @@ from trytond.model import (
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.status import processing
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.tools import timezone as tz
from trytond.transaction import Transaction, TransactionError
from trytond.worker import run_task
@@ -143,7 +143,7 @@ class Cron(DeactivableMixin, ModelSQL, ModelView):
ids = [c.id for c in sub_crons]
query = table.select(
table.id,
where=reduce_ids(table.id, ids),
where=fields.SQL_OPERATORS['in'](table.id, ids),
for_=For('UPDATE'))
cursor.execute(*query)
not_running = {i for i, in cursor}
+2 -2
View File
@@ -9,7 +9,7 @@ from trytond.i18n import lazy_gettext
from trytond.model import ModelSQL, ModelView, fields
from trytond.pool import Pool
from trytond.pyson import Eval
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
from .resource import ResourceMixin, resource_copy
@@ -52,7 +52,7 @@ class Note(ResourceMixin, ModelSQL, ModelView):
unread = {}
for sub_ids in grouped_slice(ids):
where = reduce_ids(table.id, sub_ids)
where = fields.SQL_OPERATORS['in'](table.id, sub_ids)
query = table.join(read, 'LEFT',
condition=(table.id == read.note)
& (read.user == user_id)
+6 -5
View File
@@ -15,7 +15,7 @@ from trytond.model import (
from trytond.model.exceptions import ValidationError
from trytond.pool import Pool
from trytond.pyson import Eval, If, PYSONDecoder, TimeDelta
from trytond.tools import grouped_slice, reduce_ids
from trytond.tools import grouped_slice
from trytond.transaction import Transaction
@@ -206,10 +206,10 @@ class Trigger(DeactivableMixin, ModelSQL, ModelView):
new_ids = []
for sub_ids in grouped_slice(ids):
sub_ids = list(sub_ids)
red_sql = reduce_ids(trigger_log.record_id, sub_ids)
where = fields.SQL_OPERATORS['in'](trigger_log.record_id, sub_ids)
cursor.execute(*trigger_log.select(
trigger_log.record_id, Count(),
where=red_sql & (trigger_log.trigger == self.id),
where=where & (trigger_log.trigger == self.id),
group_by=trigger_log.record_id))
number = dict(cursor)
for record_id in sub_ids:
@@ -231,10 +231,11 @@ class Trigger(DeactivableMixin, ModelSQL, ModelView):
now = datetime.datetime.fromisoformat(now)
for sub_ids in grouped_slice(ids):
sub_ids = list(sub_ids)
red_sql = reduce_ids(trigger_log.record_id, sub_ids)
where = fields.SQL_OPERATORS['in'](
trigger_log.record_id, sub_ids)
cursor.execute(*trigger_log.select(
trigger_log.record_id, Max(trigger_log.create_date),
where=(red_sql & (trigger_log.trigger == self.id)),
where=where & (trigger_log.trigger == self.id),
group_by=trigger_log.record_id))
delay = dict(cursor)
for record_id in sub_ids:
-1
View File
@@ -383,7 +383,6 @@ class ModelSQL(ModelStorage):
@classmethod
def __setup_indexes__(cls):
pool = Pool()
# Define Range index to optimise with reduce_ids
for field_name, field in cls._fields.items():
Targets = []
if isinstance(field, fields.Many2One):
+1 -47
View File
@@ -6,7 +6,6 @@ import datetime as dt
import doctest
import email.message
import os
import sys
import unittest
from copy import deepcopy
from decimal import Decimal
@@ -29,7 +28,7 @@ from trytond.tests.test_tryton import TestCase
from trytond.tools import (
cached_property, decimal_, email_, escape_wildcard, file_open, firstline,
grouped_slice, is_full_text, is_instance_method, likify, lstrip_wildcard,
pair, pairwise_longest, reduce_domain, reduce_ids, remove_forbidden_chars,
pair, pairwise_longest, reduce_domain, remove_forbidden_chars,
rstrip_wildcard, slugify, sortable_values, sqlite_apply_types,
strip_wildcard, timezone, unescape_wildcard, unpair)
from trytond.tools.chart import sparkline
@@ -56,51 +55,6 @@ class ToolsTestCase(TestCase):
'Test tools'
table = sql.Table('test')
def test_reduce_ids_empty(self):
'Test reduce_ids empty list'
self.assertEqual(reduce_ids(self.table.id, []), sql.Literal(False))
def test_reduce_ids_continue(self):
'Test reduce_ids continue list'
self.assertEqual(reduce_ids(self.table.id, list(range(10))),
sql.operators.Or(((self.table.id >= 0) & (self.table.id <= 9),)))
def test_reduce_ids_one_hole(self):
'Test reduce_ids continue list with one hole'
self.assertEqual(reduce_ids(
self.table.id, list(range(10)) + list(range(20, 30))),
((self.table.id >= 0) & (self.table.id <= 9))
| ((self.table.id >= 20) & (self.table.id <= 29)))
def test_reduce_ids_short_continue(self):
'Test reduce_ids short continue list'
self.assertEqual(reduce_ids(self.table.id, list(range(4))),
sql.operators.Or((self.table.id.in_(list(range(4))),)))
def test_reduce_ids_complex(self):
'Test reduce_ids complex list'
self.assertEqual(reduce_ids(self.table.id,
list(range(10)) + list(range(25, 30)) + list(range(15, 20))),
(((self.table.id >= 0) & (self.table.id <= 14))
| (self.table.id.in_(list(range(25, 30))))))
def test_reduce_ids_complex_small_continue(self):
'Test reduce_ids complex list with small continue'
self.assertEqual(reduce_ids(self.table.id,
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 15, 18, 19, 21]),
(((self.table.id >= 1) & (self.table.id <= 12))
| (self.table.id.in_([15, 18, 19, 21]))))
@unittest.skipIf(sys.flags.optimize, "assert removed by optimization")
def test_reduce_ids_float(self):
'Test reduce_ids with integer as float'
self.assertEqual(reduce_ids(self.table.id,
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0,
15.0, 18.0, 19.0, 21.0]),
(((self.table.id >= 1.0) & (self.table.id <= 12.0))
| (self.table.id.in_([15.0, 18.0, 19.0, 21.0]))))
self.assertRaises(AssertionError, reduce_ids, self.table.id, [1.1])
def test_reduce_domain(self):
'Test reduce_domain'
clause = ('x', '=', 'x')
+6 -42
View File
@@ -12,14 +12,12 @@ import re
import types
import unicodedata
import warnings
from array import array
from collections.abc import Iterable, Sized
from functools import cache, wraps
from itertools import chain, islice, tee, zip_longest
from sql import As, Cast, Literal, Select
from sql import As, Cast, Select
from sql.conditionals import Case
from sql.operators import Or
from trytond.const import MODULES_GROUP, OPERATORS
@@ -111,45 +109,11 @@ def get_smtp_server():
def reduce_ids(field, ids):
'''
Return a small SQL expression for the list of ids and the sql column
'''
if __debug__:
def strict_int(value):
assert not isinstance(value, float) or value.is_integer(), \
"ids must be integer"
return int(value)
else:
strict_int = int
ids = list(map(strict_int, ids))
if not ids:
return Literal(False)
ids.sort()
prev = ids.pop(0)
continue_list = [prev, prev]
discontinue_list = array('l')
sql = Or()
for i in ids:
if i == prev:
continue
if i != prev + 1:
if continue_list[-1] - continue_list[0] < 5:
discontinue_list.extend([continue_list[0] + x for x in
range(continue_list[-1] - continue_list[0] + 1)])
else:
sql.append((field >= continue_list[0])
& (field <= continue_list[-1]))
continue_list = []
continue_list.append(i)
prev = i
if continue_list[-1] - continue_list[0] < 5:
discontinue_list.extend([continue_list[0] + x for x in
range(continue_list[-1] - continue_list[0] + 1)])
else:
sql.append((field >= continue_list[0]) & (field <= continue_list[-1]))
if discontinue_list:
sql.append(field.in_(discontinue_list))
return sql
from trytond.model.fields import SQL_OPERATORS
warnings.warn(
"reduce_ids is deprecated use trytond.fields.SQL_OPERATORS['in']",
DeprecationWarning)
return SQL_OPERATORS['in'](field, ids)
def reduce_domain(domain):