edgedb-python
edgedb-python copied to clipboard
Code generator use query_single instead of query for Set result
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:
- use
query_singleinsteadquery - decorate the function returned typing as
Resultinstead oflist[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-pythonversion: 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-pythonversion: 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 };\
""",
)