diff --git a/warehouse/forklift/legacy.py b/warehouse/forklift/legacy.py index a21ccab42195..7c02a7bd1257 100644 --- a/warehouse/forklift/legacy.py +++ b/warehouse/forklift/legacy.py @@ -1530,11 +1530,6 @@ def file_upload(request): f"Invalid attestations supplied during upload: {e}", ) - # TODO: This should be handled by some sort of database trigger or a - # SQLAlchemy hook or the like instead of doing it inline in this - # view. - request.db.add(Filename(filename=filename)) - # Store the information about the file in the database. file_ = File( release=release, diff --git a/warehouse/packaging/models.py b/warehouse/packaging/models.py index 3f1b209e0722..989860fda907 100644 --- a/warehouse/packaging/models.py +++ b/warehouse/packaging/models.py @@ -25,6 +25,7 @@ Text, UniqueConstraint, cast, + event, func, or_, orm, @@ -1207,3 +1208,20 @@ class AlternateRepository(db.Model): name: Mapped[str] url: Mapped[str] description: Mapped[str] + + +@event.listens_for(File, "after_insert") +def add_filename_to_registry(mapper, connection, target): + """ + Log the new filename to the Filename (file_registry) table. + + This event listener is triggered *after* a new `File` object is + successfully inserted into the database. + + We use a direct connection-level insert (`connection.execute()`) + instead of `session.add(Filename(...))` to avoid an `SAWarning`. + Modifying the session *during* the flush process (which is when + this hook runs) is not a supported operation. This method + bypasses the session's unit-of-work tracking and is safe here. + """ + connection.execute(Filename.__table__.insert(), {"filename": target.filename})