tortoise / tortoise/tortoise-orm
Invalid postgresql query generated by update statement
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 5.6k
- Forks
- 516
- Avg merge
- 2d 21h
- Merged PRs (30d)
- 9
Description
Describe the bug
Under certain circumstances tortoise generates invalid postgesql queries.
To Reproduce
create two tortoise models with a foreign key relations like this
class RuntimeStatus(str, Enum):
IDLE: str = "idle"
EXECUTING: str = "executing"
class BatchRunStatus(str, Enum):
PLANNED: str = "planned"
QUEUED: str = "queued"
RESERVED: str = "reserved"
class BatchRun(Model):
id = fields.IntField(pk=True)
status = fields.CharEnumField(BatchRunStatus, default=BatchRunStatus.PLANNED)
runtime: ForeignKeyRelation["Runtime"] = fields.ForeignKeyField(
"models.Runtime", null=True, related_name="batch_runs"
)
class Runtime(Model):
id = fields.IntField(pk=True)
status = fields.CharEnumField(RuntimeStatus)
and execute the following query
await filter(status=BatchRunStatus.RESERVED, runtime__status=RuntimeStatus.IDLE).update(
status=BatchRunStatus.QUEUED
)
This will generate the following invalid postgresql query
UPDATE "batchrun" SET "status"='queued' FROM "batchrun" "batchrun_" LEFT OUTER JOIN "runtime" "batchrun__runtime" ON "batchrun__runtime"."id"="batchrun"."runtime_id" WHERE "batchrun"."status"='reserved' AND "batchrun__runtime"."status"='idle'
which in the end leads to the following error being raised by tortoise
tortoise.exceptions.OperationalError: invalid reference to FROM-clause entry for table "batchrun"
HINT: There is an entry for table "batchrun", but it cannot be referenced from this part of the query.
Executing the above sql statement manually (with the $1 substituted for the appropriate value) gives the more precise error
postgres=# UPDATE "batchrun" SET "status"='queued' FROM "batchrun" "batchrun_" LEFT OUTER JOIN "runtime" "batchrun__runtime" ON "batchrun__runtime"."id"="batchrun"."runtime_id" WHERE "batchrun"."status"='reserved' AND "batchrun__runtime"."status"='idle';
ERROR: invalid reference to FROM-clause entry for table "batchrun"
LINE 1: ..." "batchrun__runtime" ON "batchrun__runtime"."id"="batchrun"...
^
HINT: There is an entry for table "batchrun", but it cannot be referenced from this part of the query.
Expected behavior
I expect a valid postgresql statement to be generated. The actual problem is that postgresql is strict with alias names. If you create a join with aliases you actually have to use the alias in the corresponding ON statement. So the following postgresql statement works
UPDATE "batchrun" SET "status"=$1 FROM "batchrun" "batchrun_" LEFT OUTER JOIN "runtime" "batchrun__runtime" ON "batchrun__runtime"."id"="batchrun_"."runtime_id" WHERE "batchrun_"."status"='reserved' AND "batchrun__runtime"."status"='idle';
Additional context
The postgresql server being used here is Debian 14.3-1.pgdg110+1
and the tortoise orm version used is tortoise-orm = {extras = ["asyncpg"], version = "^0.19.2"}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reproducing the two-model example and the filtered update against PostgreSQL, then trace the update query generation that produces the shown SQL. Done means the generated statement uses the aliased batchrun_ table consistently in the JOIN and WHERE clauses and executes successfully.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- postgresql, python
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100