-
-
Notifications
You must be signed in to change notification settings - Fork 480
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow the use of multiple databases #539
Conversation
@dopatraman thanks for this. Where is |
@rossmechanic no prob, happy to contribute!
Correct. Using a router crossed my mind, but it looks like argument passed to I found that if a database router sends a historical table to a separate database, the I'm open to a better way to do this. But short of hacking Django core, this seemed like the best option. Thanks! |
To me, that's a bug. Ideally, history check for it's db in the following order:
Right now, it seems that the history table only accept its base table's db, overruling anything else. I'd want the solution to include options 1 and 2 without breaking anything for current users (we can then deprecate if necessary before DSH3). |
I like this solution. However, this means we're explicitly overriding the Side note, I'm unable to run the test and format tasks. |
03f8166
to
59afcf2
Compare
Don't think anyone should be using |
Why can't you test or format? |
@rossmechanic ok, I've updated the code. FWIW, I'm not 100% happy with how I've written this because the root of the problem seems to be coming from Django itself. Do you know if there is a way to override whatever is passing |
8d3a3a0
to
951197f
Compare
Codecov Report
@@ Coverage Diff @@
## master #539 +/- ##
==========================================
+ Coverage 97.75% 97.75% +<.01%
==========================================
Files 17 17
Lines 847 848 +1
Branches 117 117
==========================================
+ Hits 828 829 +1
Misses 8 8
Partials 11 11
Continue to review full report at Codecov.
|
This is my output for
This strikes me as strange since, IIRC, tox should run tests across all of the missing environments. @rossmechanic |
@dopatraman you need to install pyenv and then install all of the different versions of python using pyenv. Tox can't do anything if the interpreter doesn't exist locally. If that's not in the contributing docs, feel free to add it |
@rossmechanic great, that did the trick. I'm in a bit of a quandary re: code climate style issues. The complaint is that a function should not have greater than X parameters. Unfortunately, we need to pass an extra argument to Is it possible to relax the rules regarding parameter count for this feature? |
@dopatraman yep I can override the codeclimate issue to merge. DWAI. I'll look into this pr more closely this weekend and get any last feedback before merging |
@rossmechanic any progress on reviewing the PR? |
@dopatraman it doesn't currently respect routers. Ideally we could have a router as the fallback rather than the base model's history. You see any way to do that? |
Not sure I understand what you mean by having the router as a fallback? |
@dopatraman so ideally, we have:
Right now, this PR only respects 1 and 3, but if the router were to send these historical tables elsewhere, it wouldn't work. Not sure how to fix this though. Need to look more deeply into it |
Sorry, I'm not sure I follow. In theory, the user of this library would have their own router that sends the historical tables to some database. All that matters is that future records are saved to the same database, right? |
Right now that router wouldn't work tho, right? Since the router_db will be overruled by the base table's db? Or if I specify in the router that all models starting with |
The db router would have to route the historical tables to the desired database. The router could do this any number of ways, for instance:
The implementation of these routing methods is up to the developer. If your concern is about automating this type of configuration, it may worth looking into, but I wonder if it is within the scope of this pull request. Users of this library may want to organize their historical tables any number of ways -- as of now they have the freedom to write a db router class that meets their specifications without having the library impose something onto them. |
My concern was that the |
I see... to my knowledge the historical tables were never using the The reason for this pull request was to force an override of the default |
There is no |
Regardless, can you add docs and tests? |
re: docs and tests, will do. re: router fall back I see what you're saying now. In theory we could capture the router's context when the migrations are run, and then compare the context to the inputs passed to I'd be in favor of merging this in first and attempting the latter afterwards. I'd be happy to help build it out 😄 |
Great. Add the docs and tests and I'll do another pass through. I agree it should be another PR, but didn't want to do anything here that made that second PR more difficult to implement. Thanks for your help! |
Yea, happy with this PR. Add docs and tests and I'll merge 👍 |
re: tests, I'm not able to find where we run migrations on the test databases. The |
c5e04e5
to
16be097
Compare
As mentioned in the reply above, I don't think we can hook into the router without modifying django core. Since I'm on a bit of a time crunch and this changeset does not break anything that already exists, would it be possible to merge and address the |
b0e62ed
to
6f116c7
Compare
@dopatraman what I'm saying is more along the lines of this: Pass a parameter to
With that, if you pass |
I don't believe this would have the desired effect because the For illustration purposes -- suppose we have an operational model and its associated historical model. By the time TLDR, without a I don't know how we can get around forcing a table parameter on the historical record without modifying django core, which I think is outside the scope of this PR. |
@dopatraman If you look at https://github.com/treyhunner/django-simple-history/blob/6b113e3e90f2405a2d9a9479bdf91afc0e695ab0/simple_history/models.py#L477 , that's where the instance is saved. If we pass Now, if you look at what the https://github.com/django/django/blob/master/django/db/models/base.py#L700 Thus, the method described above should defer to routers. Essentially, I think we made a mistake by merging #507, but adding this flag would allow us to go back to a state where historical models can be completely controlled by routers. |
I'm still not sure I understand the interface. What does From what I gather, if |
@dopatraman ‘use_base_table_db’ (actually let’s call it use_base_model_db) would mean whether or not we always use the base model’s DB. When I say base model, I mean MyModel as opposed to HistoricalMyModel. The reason we want use_base_model_db to default to True is to keep this backward compatible, wed likely change the default in the next major version |
It looks like the TestDbRouter still does not migrate the models properly. I am not clear on how the migrations happen -- I am not able to hit breakpoints or log statements in the |
79a9e3c
to
3179e5b
Compare
I've done my best to repair the tests and refactor. Tell me what you think. IMO, the test configuration is kind of funky. I'm not sure we're using the TestDbRouter in the best way. FWIW, the codebase I'm using that imports simple_history is able to migrate historical tables without any issues. I'm happy to take a look at how to improve this in a separate ticket. |
Fixed the tests for you in this branch https://github.com/treyhunner/django-simple-history/tree/using-separate-db. You can copy them over from there. You've put a lot of work into this PR so I want your version to be the one merged. Essentially just added another router particularly for this test case. Migrations are difficult to test so we don't have to worry about them, but the tests do test that the base model and history model are read and written to the correct (separate) dbs. For the record, migrations are run before the test suite which is why they're hard to test. If you copy those tests over and update the docs, I'm happy to merge @dopatraman |
Thank you for the assist. I like your solution -- a separate router for the override is a clean way to test. I've cherry-picked your changes onto this branch. It seemed quicker and I'm happy to share the credit. The tests are passing now... if you're ready, let's merge! |
@dopatraman Looks good to me! Just need to update the docs and I'll merge |
a55bedd
to
10aa065
Compare
Looks like we're good to go. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! Thanks @dopatraman
Right now, this library does not support saving historical to a database separate from its operational model. This PR allows the historical record to be saved to the same db as the historical record table.
Description
alias
contained in the historical instance.Motivation and Context
As of now, the historical records are created using the database associated with the operational model being tracked, not the database associated with the historical table. That means if the operational model is in a separate database, the library attempts to look up the historical table in the operational database, and subsequently fails.
How Has This Been Tested?
So far, I have not been able to get the full test suite to run locally.
That being said, the tests involve creating a record on a second database by passing the db name into the
HistoricalRecords
constructor and then asserting its existence.Types of changes
Checklist:
make format
command to format my codeAUTHORS.rst
CHANGES.rst