Skip to content

[16.0][IMP] database_cleanup: purge orphaned attachments - #3566

Merged
OCA-git-bot merged 1 commit into
OCA:16.0from
cetmix:16.0-t5258-database_cleanup-orphaned-attachments-clean
Aug 21, 2026
Merged

[16.0][IMP] database_cleanup: purge orphaned attachments#3566
OCA-git-bot merged 1 commit into
OCA:16.0from
cetmix:16.0-t5258-database_cleanup-orphaned-attachments-clean

Conversation

@Aldeigja

Copy link
Copy Markdown

Add wizard to list ir.attachment records whose store_fname points to a missing file on disk when storage is "file", and allow purging those rows.

@Aldeigja
Aldeigja force-pushed the 16.0-t5258-database_cleanup-orphaned-attachments-clean branch from 699d8f0 to ab70051 Compare March 20, 2026 10:03

@StefanRijnhart StefanRijnhart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Judging from the name of the PR and the patterns from this module, I would have expected signalling attachments where the model no longer exists or the res_id is not present as a record. This makes sense as well, but to make it explicit what the issue is with each attachment (and to prepare for extension with other possible error conditions), would you mind adding a reason field to the wizard line model as is done in cleanup.purge.line, with for now a fixed reason like 'File missing in filestore'?

Comment thread database_cleanup/tests/test_purge_attachments.py Outdated
Comment thread database_cleanup/tests/test_purge_attachments.py
@Aldeigja
Aldeigja force-pushed the 16.0-t5258-database_cleanup-orphaned-attachments-clean branch from b372147 to 95fb498 Compare April 3, 2026 23:00
@Aldeigja
Aldeigja requested a review from StefanRijnhart April 3, 2026 23:12

@StefanRijnhart StefanRijnhart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates! Please squash commits.

Comment thread database_cleanup/models/purge_attachments.py Outdated
Comment thread database_cleanup/models/purge_attachments.py
Comment thread database_cleanup/models/purge_attachments.py Outdated
@Aldeigja
Aldeigja force-pushed the 16.0-t5258-database_cleanup-orphaned-attachments-clean branch from 95fb498 to e8b0061 Compare April 4, 2026 17:08
@Aldeigja
Aldeigja requested a review from StefanRijnhart April 4, 2026 17:11

@StefanRijnhart StefanRijnhart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the error message is stored correctly.

Image

Usability wise, I think as a user I would want to see some more information about the attachments, the res_model, res_id and res_name, with or without optional visibility. Is this not something that you want for your own purposes?

@Aldeigja

Aldeigja commented Apr 6, 2026

Copy link
Copy Markdown
Author

@StefanRijnhart

Usability wise, I think as a user I would want to see some more information about the attachments, the res_model, res_id and res_name, with or without optional visibility.
Is this not something that you want for your own purposes?

Our objective in creating this PR was to clean approximately 15,000 orphaned attachments simultaneously. We didn’t have to inspect every single attachment.
However, if users need to check details, they can do so by clicking on the line, opening the line pop-up, and then accessing the attachment form.
image

@StefanRijnhart StefanRijnhart left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, leaving my last comment as a nice to have. Nice work!

from .common import Common, environment


# Use post_install to get all models loaded more info: odoo/odoo#13458

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this comment belongs here


:var orphan: ir.attachment with backing file removed via os.unlink
:var valid: ir.attachment with file intact
:return: None

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove redundant lines such as ":return: None" to avoid unnecessary noise

Comment thread database_cleanup/models/purge_attachments.py
@Aldeigja
Aldeigja force-pushed the 16.0-t5258-database_cleanup-orphaned-attachments-clean branch from e8b0061 to 831b3af Compare August 14, 2026 11:27
@Aldeigja
Aldeigja force-pushed the 16.0-t5258-database_cleanup-orphaned-attachments-clean branch from 831b3af to 49ce4fe Compare August 14, 2026 11:41
@Aldeigja
Aldeigja requested a review from tendil August 14, 2026 11:42

@tagged("post_install", "-at_install")
class TestCleanupPurgeLineAttachment(Common):
def setUp(self):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please rewrite it to use setUpClass, since that works faster

@Aldeigja

Copy link
Copy Markdown
Author

It appears that the CI failure here is unrelated to this change. Check this comment.

@tendil tendil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review: LGTM

@Aldeigja
Aldeigja force-pushed the 16.0-t5258-database_cleanup-orphaned-attachments-clean branch from 1a94b71 to c7c414d Compare August 17, 2026 10:52
last_id = 0
ir_attachment = self.env["ir.attachment"]
while True:
rows = ir_attachment.search_read(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since the purpose of this change is to avoid MemoryError on very large databases, please evict the processed batch from the cache before fetching the next one using invalidate_recordset(["store_fname", "name"])

search_read() limits the size of a single batch here but does not limit the total memory usage of the orm cache

self.assertIn(self.orphan_attach_id, line_attachment_ids)
self.assertNotIn(self.valid_attach_id, line_attachment_ids)

def test_find_does_not_prefetch_unrequested_attachment_fields(self):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please add a regression test that processes multiple batches (the batch size can be patched to a small value) and also verifies that the processed batch is evicted from the cache

otherwise the implementation could start retaining all processed attachments in the Environment cache again while this test would still pass

@tendil tendil left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: LGTM

@StefanRijnhart

Copy link
Copy Markdown
Member

@Aldeigja Thanks for the continued effort following up the comments! Can you squash the commits?

@Aldeigja
Aldeigja force-pushed the 16.0-t5258-database_cleanup-orphaned-attachments-clean branch from 63d90e2 to eee5cc5 Compare August 20, 2026 11:34
Add wizard to list ir.attachment records whose store_fname points to a
missing file on disk when storage is "file", and allow purging those
rows.

task 5258
@Aldeigja
Aldeigja force-pushed the 16.0-t5258-database_cleanup-orphaned-attachments-clean branch from eee5cc5 to 84e80c2 Compare August 20, 2026 11:42
@StefanRijnhart

Copy link
Copy Markdown
Member

And CI was fixed in the mean time by #3707, so ready for merge.

/ocabot merge major

@OCA-git-bot

Copy link
Copy Markdown
Contributor

What a great day to merge this nice PR. Let's do it!
Prepared branch 16.0-ocabot-merge-pr-3566-by-StefanRijnhart-bump-major, awaiting test results.

@OCA-git-bot
OCA-git-bot merged commit 29270ed into OCA:16.0 Aug 21, 2026
9 checks passed
@OCA-git-bot

Copy link
Copy Markdown
Contributor

Congratulations, your PR was merged at b31cab9. Thanks a lot for contributing to OCA. ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants