You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo中reporting_period_id字段点击触发psycopg2类型转换错误

问题排查:Reporting Period字段筛选时的PostgreSQL类型错误

我希望reporting_period_id字段仅显示所选特定财年内、与output_indicator_id匹配的报告期,但点击该字段时触发了数据库类型错误,以下是相关代码与错误信息:

模型代码

class ProgrammeLinking(models.Model):
    _name = 'mis.programme.linking'
    _description = 'linking and allocations'
    _rec_name = "financial_year_id"

    financial_year_id = fields.Many2one('res.financial.year',string='Financial Year')

    output_indicator_id = fields.Many2one('mis.output.indicator',string='APP Output indicator', store=True)
    allowed_output_indicator_ids = fields.Many2many(
        'mis.output.indicator', 
        compute="_compute_allowed_output_indicator_ids"
    )
    reporting_period_id = fields.Many2one('mis.create.link.national.app', string='Reporting Period')
    allowed_reporting_period_ids = fields.Many2many(
        'mis.create.link.national.app',
        compute="_compute_allowed_reporting_period_ids"
    )


    def _get_current_fy_programme_linking(self):
        for rec in self:
            return self.env['mis.create.link.national.app'].search([
                ('financial_year_id','=', rec.financial_year_id.id)
            ])


    @api.depends('outcome_id')
    def _compute_allowed_output_indicator_ids(self):
        for rec in self:
            if rec.outcome_id:
                fy_linkings = self._get_current_fy_programme_linking()
                output = fy_linkings \
                    .filtered(lambda l: l.outcome_id.id == rec.outcome_id.id) \
                    .mapped('output_indicator_id')
                _logger.info(f"Filtered ou {output}")
                rec.allowed_output_indicator_ids = output
            else:
                rec.allowed_output_indicator_ids = False

    
    @api.depends('output_indicator_id')
    def _compute_allowed_reporting_period_ids(self):
        for rec in self:
            if rec.output_indicator_id:
                fy_linkings = self._get_current_fy_programme_linking()
                period = fy_linkings \
                    .filtered(lambda l: l.output_indicator_id.id == rec.output_indicator_id.id) \
                    .mapped('reporting_period')
                _logger.info(f"Filtered periods {period}")
                rec.allowed_reporting_period_ids = period
            else:
                rec.allowed_reporting_period_ids = False

视图代码

<field name="allowed_output_indicator_ids" invisible="1"/>
<field name="output_indicator_id" required="1" options="{'no_create': True, 'no_open': True}" domain="[('id','in', allowed_output_indicator_ids)]"/>

<field name="allowed_reporting_period_ids" invisible="1"/>
<field name="reporting_period_id" required="1" options="{'no_create': True, 'no_open': True}" domain="[('id','in', allowed_reporting_period_ids)]"/>

错误信息

Traceback (most recent call last):
  File "C:\odoo14\server\odoo\http.py", line 639, in _handle_exception
    return super(JsonRequest, self)._handle_exception(exception)
  File "C:\odoo14\server\odoo\http.py", line 315, in _handle_exception
    raise exception.with_traceback(None) from new_cause
psycopg2.errors.InvalidTextRepresentation: invalid input syntax for type integer: "quarterly"
LINE 1: ...p" WHERE ("mis_create_link_national_app"."id" in ('quarterly...
                                                             ^

关键说明

mis.create.link.national.app模型中的reporting_period是选择字段,当前财年内该字段值为"quarterly"。


问题根源

allowed_reporting_period_ids是mis.create.link.national.app的多对多字段,本应存储该模型的记录ID,但当前代码用.mapped('reporting_period')提取的是选择字段的字符串值(如"quarterly"),而非记录ID。视图中[('id','in', allowed_reporting_period_ids)]的筛选逻辑,会把字符串当成ID传入数据库,导致PostgreSQL尝试将字符串转为整数类型时失败。

修复方案

修改_compute_allowed_reporting_period_ids方法,直接映射符合条件的mis.create.link.national.app记录,而非其reporting_period字段值:

@api.depends('output_indicator_id')
def _compute_allowed_reporting_period_ids(self):
    for rec in self:
        if rec.output_indicator_id:
            fy_linkings = self._get_current_fy_programme_linking()
            # 直接筛选符合条件的记录,而非提取字段值
            period_records = fy_linkings.filtered(
                lambda l: l.output_indicator_id.id == rec.output_indicator_id.id
            )
            _logger.info(f"Filtered period records {period_records}")
            rec.allowed_reporting_period_ids = period_records
        else:
            rec.allowed_reporting_period_ids = False

额外优化点

_get_current_fy_programme_linking方法存在逻辑问题:循环内直接return会只处理第一条记录,建议重构为批量查询:

def _get_current_fy_programme_linking(self):
    # 批量查询所有关联财年的记录,避免循环内重复查询
    fy_ids = self.mapped('financial_year_id.id')
    return self.env['mis.create.link.national.app'].search([
        ('financial_year_id', 'in', fy_ids)
    ])

内容的提问来源于stack exchange,提问作者MarkHenri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 23:01:22