agronholm / agronholm/sqlacodegen

foreign keys with cascade delete not correctly generated

Abierto
#387 4 comentarios 2 reacciones 1 asignado Reclamado por @sheinbergon Ver en GitHub
bug
Lenguaje dominante
Python
Estrellas
2.4k
Forks
284
Merge medio
2 d 1 h
PR fusionados (30 d)
1

Descripción

### Things to check first

- [x] I have searched the existing issues and didn't find my bug already reported there

- [x] I have checked that my bug is still present in the latest release

### Sqlacodegen version

3.0.0

### SQLAlchemy version

2.0.35

### RDBMS vendor

PostgreSQL

### What happened?

I have a table that references another with a foreign key. The foreign key is set to `ON CASCADE DELETE`

When attempting to delete a parent entity with sqlalchemy e.g.

```
item = session.get(id)
session.delete(item)
session.commit()
```

I get an error
```
sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) null value in column "work_item_id" of relation "work_item_vote" violates not-null constraint
DETAIL: Failing row contains (04a2a98c-7310-4c3f-9608-389c1ed73098, null, test@example.com).

[SQL: UPDATE work_item_vote SET item_id=%(item_id)s::UUID WHERE item_vote.item_vote_id = %(item_vote_item_vote_id)s::UUID]
[parameters: {'item_id': None, 'item_vote_item_vote_id': UUID('04a2a98c-7310-4c3f-9608-389c1ed73098')}]
```

where SQLAlchemy is attempting to update the child row instead of deleting it

The generated code I get for the tables are
```
class Item(Base):
__tablename__ = "item"
__table_args__ = (PrimaryKeyConstraint("item_id", name="item_pkey"),)

item_id: Mapped[uuid.UUID] = mapped_column(
Uuid, primary_key=True, server_default=text("uuid_generate_v4()")
)
title: Mapped[str] = mapped_column(String)
status: Mapped[str] = mapped_column(String)
created_at: Mapped[datetime.datetime] = mapped_column(DateTime)
last_updated_at: Mapped[datetime.datetime] = mapped_column(DateTime)
description: Mapped[Optional[str]] = mapped_column(String)

item_vote: Mapped[List["ItemVote"]] = relationship(
"ItemVote", back_populates="item"
)

class ItemVote(Base):
__tablename__ = "item_vote"
__table_args__ = (
ForeignKeyConstraint(
["item_id"],
["item.item_id"],
ondelete="CASCADE",
name="item_vote_item_id_fkey",
),
PrimaryKeyConstraint("item_vote_id", name="item_vote_pkey"),
)

item_vote_id: Mapped[uuid.UUID] = mapped_column(
Uuid, primary_key=True, server_default=text("uuid_generate_v4()")
)
item_id: Mapped[uuid.UUID] = mapped_column(Uuid)
user_id: Mapped[str] = mapped_column(String)

item: Mapped["Item"] = relationship(
"Item", back_populates="item_vote"
)
```

the generated model for Item seems to be missing `cascade='all, delete'` or `passive_deletes`

### Database schema for reproducing the bug

```
CREATE TABLE item (
item_id uuid DEFAULT uuid_generate_v4() NOT NULL,
title varchar NOT NULL,
description varchar NULL,
status varchar NOT NULL,
created_at timestamp NOT NULL,
last_updated_at timestamp NOT NULL,
CONSTRAINT item_pkey PRIMARY KEY (item_id)
);

CREATE TABLE item_vote (
item_vote_id uuid DEFAULT uuid_generate_v4() NOT NULL,
item_id uuid NOT NULL,
user_id varchar NOT NULL,
CONSTRAINT item_vote_pkey PRIMARY KEY (item_vote_id),
CONSTRAINT item_vote_item_id_fkey FOREIGN KEY (item_id) REFERENCES item(item_id) ON DELETE CASCADE
);
```

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.