edgedb-python icon indicating copy to clipboard operation
edgedb-python copied to clipboard

Code generator use query_single instead of query for Set result

Open goan15910 opened this issue 8 months ago • 0 comments

Describe the bug

In some scenario, the code generator wrongly generates python code that does not match the possible queried data cardinality. To be specific, the generated code of selecting the result set of updating possibly multiple objects has the following behavior:

  1. use query_single instead query
  2. decorate the function returned typing as Result instead of list[Result]

Reproduction

Using schema and query like the following:

module default {
  abstract type Resource {
    required created_at: datetime {
      readonly := true;
      default := datetime_of_statement();
    }
  }

  type Release extending Resource {
    required major: uint16 {
      readonly := true;
    };
    required minor: uint16 {
      readonly := true;
    };
    required patch: uint16 {
      readonly := true;
    };
    required disabled: bool {
      default := false;
    };
    required updated_at: datetime {
      rewrite insert, update using (datetime_of_statement());
    };

    constraint exclusive on ((.major, .minor, .patch));
  }
}
select (
   update Release
   set {disabled := true}
) { id };

The generated python code will be:

# AUTOGENERATED FROM '../test_edgeql/test.edgeql' WITH:
#     $ gel-py -I local --dir ../test_edgeql


from __future__ import annotations
import dataclasses
import gel
import uuid


class NoPydanticValidation:
    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        # Pydantic 2.x
        from pydantic_core.core_schema import any_schema
        return any_schema()

    @classmethod
    def __get_validators__(cls):
        # Pydantic 1.x
        from pydantic.dataclasses import dataclass as pydantic_dataclass
        _ = pydantic_dataclass(cls)
        cls.__pydantic_model__.__get_validators__ = lambda: []
        return []


@dataclasses.dataclass
class TestResult(NoPydanticValidation):
    id: uuid.UUID


async def test(
    executor: gel.AsyncIOExecutor,
) -> TestResult:
    return await executor.query_single(
        """\
        select (
           update Release
           set {disabled := true}
        ) { id };\
        """,
    )

Expected behavior

The generated function should be decorated as list[TestResult] and use executor.query instead.

Versions (please complete the following information):

Local development environment

  • OS: macOS Sonoma 14.6.1
  • EdgeDB version: 6.4+e5a21c9
  • EdgeDB CLI version: 7.1.1+616a110
  • edgedb-python version: gel 3.0.1
  • Python version: 3.12.2

CI codegen environment

  • OS: Debian GNU/Linux 12 (bookworm)
  • EdgeDB version: 6.4+1240dde
  • EdgeDB CLI version: 7.1.1+754cfa2
  • edgedb-python version: gel 3.0.1
  • Python version: 3.12.9

Additional context

This behavior does not occur after performing the following migration (for testing purpose):

{
  ALTER TYPE default::Release {
      DROP PROPERTY updated_at;
  };
};

The generated python will become as expected:

# AUTOGENERATED FROM '../test_edgeql/test.edgeql' WITH:
#     $ gel-py --dir ../test_edgeql


from __future__ import annotations
import dataclasses
import gel
import uuid


class NoPydanticValidation:
    @classmethod
    def __get_pydantic_core_schema__(cls, _source_type, _handler):
        # Pydantic 2.x
        from pydantic_core.core_schema import any_schema
        return any_schema()

    @classmethod
    def __get_validators__(cls):
        # Pydantic 1.x
        from pydantic.dataclasses import dataclass as pydantic_dataclass
        _ = pydantic_dataclass(cls)
        cls.__pydantic_model__.__get_validators__ = lambda: []
        return []


@dataclasses.dataclass
class TestResult(NoPydanticValidation):
    id: uuid.UUID


async def test(
    executor: gel.AsyncIOExecutor,
) -> list[TestResult]:
    return await executor.query(
        """\
        select (
           update Release
           set {disabled := true}
        ) { id };\
        """,
    )

goan15910 avatar Mar 28 '25 06:03 goan15910