# Fault: cannot execute nextval() in a read-only transaction

**URL:** <https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275>\
**Category:** Developer\
**Created:** [February 4, 2025, 2:01pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275 "2025-02-04T14:01:30Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![maehder](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/m/cdc98d/32.png) [@maehder](https://discuss.tryton.org/u/maehder)\
**Post date:** [February 4, 2025, 2:01pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/1 "2025-02-04T14:01:30Z")

</div>

Hi there and thank you in advance.

I try to implement a simple template system for analyses in my laboratory module. The goal is to define a function that creates ‘parameter’ records that are linked to my ‘analysis’ record via One2Many when a template is chosen.

The ‘Analysis’ model looks like this.

```auto
class Analysis(ModelSQL, ModelView):
    'Analysis'
    __name__ = 'toxicology.analysis'

    name = fields.Char('Analysis Name')

    analysis_template = fields.Many2One('toxicology.analysis_template', 'Analysis Template')

    parameter = fields.One2Many('toxicology.parameter', 'analysis', 'Parameter')

```

The function that is supposed to work looks like this:

```auto
    @fields.depends('analysis_template')
    def on_change_with_parameter(self):
        if self.analysis_type:
            pool = Pool()
            Parameter = pool.get('toxicology.parameter')

            parameters = []

            for parameter in self.analysis_template.parameter:
                parameters.append({
                    'analysis': self.id,
                    'analyte': parameter.analyte,
                    'result': parameter.result,
                    'uom': parameter.uom and parameter.uom.id,
                    })

            Parameter.create(parameters)

```

I do however end up with the following error message “Fault: cannot execute nextval() in a read-only transaction” which indicates that this is approach is not meant to write to the database.

Is there any way I can achieve this?

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [February 4, 2025, 2:41pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/2 "2025-02-04T14:41:42Z")

</div>

`on_change` methods are execute in read-only transaction because we decided that it was a bad idea to allow them to have side-effect (because there are no guarantee that the client will call them neither in which order).

So instead of creating parameters, you should assign new parameter instances (unsaved) to the `One2Many`.  
Also you must not use a `on_change_with` because this form can only return a value for the corresponding field but instead probably `on_change_analysis_type`.

---

<div class="post-metadata">

**Author:** ![maehder](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/m/cdc98d/32.png) [@maehder](https://discuss.tryton.org/u/maehder)\
**Post date:** [February 4, 2025, 3:16pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/3 "2025-02-04T15:16:56Z")

</div>

Thank you a lot! The following code works like a charm:

```auto
    @fields.depends('analysis_template', 'parameter')
    def on_change_analysis_template(self):
        if self.analysis_template:
            self.parameter = self.analysis_template.parameter

```

However, when I create an ‘analysis’ record from another form it gives me the following error “Fault: (Pool().get(‘toxicology.analysis’)(\*\*{}), ‘parameter’)”.

I guess it’s due to the fact, that the record wasn’t yet created. Would it make sense to implement an “On Creation”-Trigger for that case?

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [February 4, 2025, 3:57pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/4 "2025-02-04T15:57:03Z")

</div>

I do not know if `parameter` is a `One2Many` or a `Many2Many` but if it is a `One2Many` you can not assign existing instance to it but you must assign new unsaved instances.

---

<div class="post-metadata">

**Author:** ![maehder](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/m/cdc98d/32.png) [@maehder](https://discuss.tryton.org/u/maehder)\
**Post date:** [February 4, 2025, 4:01pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/5 "2025-02-04T16:01:05Z")

</div>

It is a One2Many. How do I create an unsaved instance? I’m a bit puzzled.

Maybe you already have a tryton example. That would suffice.

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [February 4, 2025, 4:11pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/6 "2025-02-04T16:11:11Z")

</div>

You just need to instantiate the class. From your example it could be something like:

```auto
    @fields.depends('analysis_template', 'parameter')
    def on_change_analysis_template(self):
        pool = Pool()
        Parameter = pool.get('toxicology.parameter')
        if self.analysis_template:
            parameter = []
            for param in self.analysis_template.parameter:
                 parameter.append(Parameter(
                     'analyte': param.analyte,
                     'result': param.result,
                     'uom': param.uom))
            self.parameter = parameter

```

_PS: I would strongly suggest to use plural form for `xxx2Many` fields, the code would be much more easier to read and reason._

---

<div class="post-metadata">

**Author:** ![maehder](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/m/cdc98d/32.png) [@maehder](https://discuss.tryton.org/u/maehder)\
**Post date:** [February 5, 2025, 1:48pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/7 "2025-02-05T13:48:32Z")

</div>

Thank you for your code suggestion, instantiating the class makes of course sense. I adjusted the syntax of the instantiating and included your suggestion of making xxx2Many field names plural. I ended up with this method:

```auto
    @fields.depends('analysis_template', 'parameters')
    def on_change_analysis_template(self):
        pool = Pool()
        Parameter = pool.get('toxicology.parameter')

        if self.analysis_template:
            parameters = []

            for param in self.analysis_template.parameters:
                parameters.append(Parameter(
                    analysis = self.id,
                    analyte = param.analyte,
                    result = param.result,
                    uom = param.uom and param.uom.id,
                    ))

            self.parameters = parameters

```

Again it works within a created record, it works when creating a new “Analysis” record from the “Analysis” Tree View, but not if I try to create a new “Analysis” record from within another form (e. g. a “Sample” form that is linked to “Analysis” using another One2Many.  
Then it gives me this error:

```auto
Traceback (most recent call last):
  File "/trytond/wsgi.py", line 110, in dispatch_request
    return endpoint(request, **request.view_args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/trytond/protocols/dispatcher.py", line 44, in rpc
    return methods.get(request.rpc_method, _dispatch)(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/trytond/wsgi.py", line 76, in wrapper
    return func(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/trytond/protocols/wrappers.py", line 208, in wrapper
    result = func(request, pool, *args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/trytond/protocols/dispatcher.py", line 221, in _dispatch
    result = rpc.result(meth(inst, *c_args, **c_kwargs))
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/trytond/model/fields/field.py", line 195, in on_change_result
    return record._changed_values
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/trytond/model/modelview.py", line 891, in _changed_values
    assert hasattr(init_record, fname), (init_record, fname)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
AssertionError: (Pool().get('toxicology.analysis')(**{}), 'parameters')

Fault: (Pool().get('toxicology.analysis')(**{}), 'parameters')

```

I don’t understand why one unsaved record works and the other one does not. I hope you have any idea.

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [February 5, 2025, 2:06pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/8 "2025-02-05T14:06:14Z")

</div>

> [@maehder](#):
>
> ` analysis = self.id,`

You must not set the reverse `Many2One` value especially when it is a negative id.

---

<div class="post-metadata">

**Author:** ![maehder](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/m/cdc98d/32.png) [@maehder](https://discuss.tryton.org/u/maehder)\
**Post date:** [February 5, 2025, 2:43pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/9 "2025-02-05T14:43:27Z")

</div>

Thank you for your answer. I deleted the line. But the error persists.

---

<div class="post-metadata">

**Author:** ![ced](https://discuss-cdn.tryton.org/user_avatar/discuss.tryton.org/ced/32/1237_2.png) [@ced](https://discuss.tryton.org/u/ced)\
**Post date:** [February 5, 2025, 3:06pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/10 "2025-02-05T15:06:56Z")

</div>

It looks like the client does not have the `parameters` field in the view.  
So it is not possible to calculate accurate modification.

---

<div class="post-metadata">

**Author:** ![maehder](https://discuss-cdn.tryton.org/letter_avatar_proxy/v4/letter/m/cdc98d/32.png) [@maehder](https://discuss.tryton.org/u/maehder)\
**Post date:** [February 5, 2025, 3:27pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/11 "2025-02-05T15:27:39Z")

</div>

That was the last piece of the puzzle. Thank you very much for your patience!

---

<div class="post-metadata">

**Author:** ![system](https://discuss-cdn.tryton.org/uploads/default/original/1X/c6f8ec0a40525cdcd50058c734283450a4b3d38b.png) [@system](https://discuss.tryton.org/u/system)\
**Post date:** [February 6, 2025, 3:28pm UTC](https://discuss.tryton.org/t/fault-cannot-execute-nextval-in-a-read-only-transaction/8275/12 "2025-02-06T15:28:37Z")

</div>

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.
