Skip to content

PostgreSQL on_conflict_do_update parameters cannot be rendered inline #13110

@loic-simon

Description

@loic-simon

Describe the bug

The compile option "literal_binds": True is not taken into account when compiling PostgreSQL-specific Insert.on_conflict_do_update.set_ parameter.

Optional link from https://docs.sqlalchemy.org which documents the behavior that is expected

https://docs.sqlalchemy.org/en/21/faq/sqlexpressions.html#rendering-bound-parameters-inline

SQLAlchemy Version in Use

2.0.46

DBAPI (i.e. the database driver)

N/A

Database Vendor and Major Version

N/A

Python Version

3.13.2

Operating system

OSX

To Reproduce

from sqlalchemy import Column, Integer, MetaData, Table
from sqlalchemy.dialects.postgresql import dialect, insert

t = Table("test", MetaData(), Column("id", Integer, primary_key=True))

stmt = insert(t).values({"id": 1}).on_conflict_do_update(constraint=t.primary_key, set_={"id": 2})

print(stmt.compile(dialect=dialect(), compile_kwargs={"literal_binds": True}))

Error

Output:

INSERT INTO test (id) VALUES (1) ON CONFLICT (id) DO UPDATE SET id = %(param_1)s

Expected output:

INSERT INTO test (id) VALUES (1) ON CONFLICT (id) DO UPDATE SET id = 2

Additional context

  • Reproduced in 1.4.54, same output
  • Reproduced in 2.0b1, with a slightly different output (additional cast at the end: INSERT INTO test (id) VALUES (1) ON CONFLICT (id) DO UPDATE SET id = %(param_1)s::INTEGER)

I suppose the issue is more broad that this single parameter, I did not dig further for now.

Thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions