Skip to content

Conversation

OscarVanL
Copy link
Contributor

@OscarVanL OscarVanL commented Aug 6, 2025

In #800 I identified a mistake in the transaction handling in the package. This meant that transactions were always started for the default DB alias, even if the DATABASE_ROUTER used by the project would actually result in silk models being written to a different DB alias.

In my scenario, it caused my application to crash as I do not have a configuration set for the default alias.

The fix I have applied is similar to one I found in jazzband/django-axes#1109, where same same bug was once present in django-axes (this is another package I use in my project where I do not encounter this bug).

Assumptions

I have used router.db_for_write(models.SQLQuery) to determine the DB alias to use for the transaction. I picked models.SQLQuery at random.

This makes an assumption that all of silk's models are routed to the same DB alias. I think this is a fair assumption, but technically someone could make a weird setup where some silk models are routed to one DB alias, and other models to another DB alias. This approach does not handle this.

Testing

I have performed manual testing with these changes in my project that was broken prior to this change. It solves the issue.

I spent far too long trying to write some test cases for this change, but it was just far too difficult. Django didn't seem to permit using override_settings to override the DATABASES config for a specific test class/case. In the end it proved too challenging, so I have not produced any tests.

I think the change is sufficiently low risk that perhaps we can accept this omission.

@OscarVanL OscarVanL marked this pull request as ready for review August 6, 2025 17:16
@albertyw albertyw mentioned this pull request Aug 10, 2025
@@ -142,28 +143,29 @@ def process_request(self, request):
request_model = RequestModelFactory(request).construct_request_model()
DataCollector().configure(request_model, should_profile=should_profile)

@transaction.atomic()
Copy link
Member

Choose a reason for hiding this comment

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

Looking at the transaction.atomic implementation in https://github.com/albertyw/django/blob/master/django/db/transaction.py#L316, this looks like it can be modified into transaction.atomic(using=router.db_for_write(models.SQLQuery)) instead of converting into a with block

Other examples: https://sourcegraph.com/search?q=context%3Aglobal+%40transaction.atomic%28using&patternType=keyword&sm=0&df=%5B%22lang%22%2C%22Python%22%2C%22lang%3Apython%22%5D&__cc=1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree that I prefer it using the annotation to avoid a level of indentation. I made the suggested change successfully for SilkyMiddleware's _process_response, but unfortunately for the other cases there are issues with scoping...

In SQLQueryManager when I reference SQLQuery in the annotation, if I order SQLQueryManager before SQLQuery, it's not in scope in the annotation.
image

If I order SQLQueryManager after SQLQuery, then SQLQueryManager is not in scope of the SQLQuery class:
image

Additionally, in the save and delete functions I run into similar issues, I guess because neither self or SQLQuery are in scope in the annotation:
image

In both cases I could also solve this by referencing some arbitrary other silk model class that is defined earlier, but it feels weird to reference a different models in SQLQuery's save/delete/Query manager. It might mislead someone that there is some relationship between the models that doesn't actually exist.

In these cases I decided to leave it as-is, please let me know if you have any thoughts/disagreements.

@OscarVanL OscarVanL requested a review from albertyw August 12, 2025 09:52
Copy link

codecov bot commented Aug 12, 2025

Codecov Report

❌ Patch coverage is 94.44444% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 87.13%. Comparing base (25fc70a) to head (4b70123).
⚠️ Report is 6 commits behind head on master.

Files with missing lines Patch % Lines
silk/models.py 93.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #801      +/-   ##
==========================================
- Coverage   87.26%   87.13%   -0.14%     
==========================================
  Files          53       53              
  Lines        2160     2161       +1     
==========================================
- Hits         1885     1883       -2     
- Misses        275      278       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@albertyw albertyw merged commit befba19 into jazzband:master Aug 13, 2025
91 of 93 checks passed
@OscarVanL
Copy link
Contributor Author

Thanks for the help with this and quick reviews!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants