-
Notifications
You must be signed in to change notification settings - Fork 1
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
Revision 7b139906ac46: Add NOT NULL constraints to certain Variable (meta_vars) columns #111
Conversation
Add not null constraints to three variables in the meta_vars table modify the subset data so that the constraint is not violated
8299fcb
to
16213ce
Compare
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.
Looking good so far, Johnathan.
Minor point: Suggest you run Black on
pycds/alembic/versions/7b139906ac46_add_not_null_constraint_on_meta_vars.py
tests/climate_baseline_helpers/conftest.py
to clean up their formatting.
I think it is worth creating a test to test the data migration part of the migration (hmm, a lot of repetitions there). The test have to do something very like this:
- establish a database at the previous revision
- populate the meta_vars table with some rows with null values and some without
- run the upgrade to your revision
- check that meta_vars has been updated as expected - the nulls have been replaced
See if you can figure out how to do this by looking at other tests. This particular test will be best placed alongside the smoke tests for this migration, not under behavioural
.
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.
Good work, @helfy18 ! You've done a great job of checking the schema migration. There's really only one thing left -- checks for the data migrations. Comment below outlines how.
pycds/alembic/versions/7b139906ac46_add_not_null_constraint_on_meta_vars.py
Show resolved
Hide resolved
pycds/alembic/versions/7b139906ac46_add_not_null_constraint_on_meta_vars.py
Show resolved
Hide resolved
# Set up database to version 7b139906ac46 | ||
engine, script = prepared_schema_from_migrations_left | ||
|
||
# Check that views have been added |
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.
This comment needs revising. Copy/pasta?
engine, script = prepared_schema_from_migrations_left | ||
|
||
# Check that views have been added | ||
table = inspect(engine).get_columns("meta_vars", schema=schema_name) |
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.
Excellent use of inspection to check the migration action. 💯
|
||
@pytest.mark.usefixtures("new_db_left") | ||
def test_upgrade(prepared_schema_from_migrations_left, schema_name): | ||
"""test migration from 3d50ec832e47 to 7b139906ac46. """ |
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.
We also need a check of the data migration action. That would look like the following:
- Migrate to 3d50ec832e47
- Load
meta_vars
with rows containing nulls in the migration columns. You can probably do that with a few inserts just tometa_vars
, rather than loading all kinds of stuff as the big behavioural tests do. - Migrate to 7b139906ac46
- Check the effects of the data migration
- Check the effects of the schema migration (already coded)
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.
You can find an example of this kind of two-stage upgrade test in tests/alembic_migrations/versions/v_e688e520d265_refactor_flags_association_tables
. The way the initial target revision for test_upgrade
is set up is subtle (a synonym for confusing): It is overridden by the parametrization
@pytest.mark.parametrize(
"prepared_schema_from_migrations_left", ("bdc28573df56",), indirect=True
)
of that method. You can do the same, except using of course the prior revision to this one.
If you get too stuck or confused, don't hesitate to reach out for help.
def test_downgrade( | ||
prepared_schema_from_migrations_left, alembic_config_left, schema_name | ||
): | ||
"""Test the schema migration from 7b139906ac46 to 3d50ec832e47. """ |
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.
And likewise a check of the downgrade data migration.
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.
For this one there is a call of command.downgrade()
, which I think means that I am testing the downgrade data migration. As far as not testing the upgrade though, I will add that in. I followed the views tests, as you noticed by my copy paste mistake, and that one did not run command.upgrade()
in the test_upgrade
feature, so that's why it is the way it is for me
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.
Yes, this means you are testing the downgrade migration -- both schema and data.
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.
For testing the upgrade, see my remarks above.
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.
Keep at it, @helfy18 , it's coming along well.
pycds/alembic/versions/7b139906ac46_add_not_null_constraint_on_meta_vars.py
Show resolved
Hide resolved
def test_downgrade( | ||
prepared_schema_from_migrations_left, alembic_config_left, schema_name | ||
): | ||
"""Test the schema migration from 7b139906ac46 to 3d50ec832e47. """ |
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.
Yes, this means you are testing the downgrade migration -- both schema and data.
def test_downgrade( | ||
prepared_schema_from_migrations_left, alembic_config_left, schema_name | ||
): | ||
"""Test the schema migration from 7b139906ac46 to 3d50ec832e47. """ |
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.
For testing the upgrade, see my remarks above.
|
||
@pytest.mark.usefixtures("new_db_left") | ||
def test_upgrade(prepared_schema_from_migrations_left, schema_name): | ||
"""test migration from 3d50ec832e47 to 7b139906ac46. """ |
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.
You can find an example of this kind of two-stage upgrade test in tests/alembic_migrations/versions/v_e688e520d265_refactor_flags_association_tables
. The way the initial target revision for test_upgrade
is set up is subtle (a synonym for confusing): It is overridden by the parametrization
@pytest.mark.parametrize(
"prepared_schema_from_migrations_left", ("bdc28573df56",), indirect=True
)
of that method. You can do the same, except using of course the prior revision to this one.
If you get too stuck or confused, don't hesitate to reach out for help.
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.
A bit more to do.
) | ||
|
||
command.upgrade(alembic_config_left, "+1") | ||
|
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.
After the migration check that the nulls in the row(s) you inserted have been set to the expected non-null values (or just not null).
"""Test the schema migration from 7b139906ac46 to 3d50ec832e47. """ | ||
|
||
# Set up database to version 7b139906ac46 | ||
engine, script = prepared_schema_from_migrations_left |
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.
Please add the downgrade data migration check: non-null values to nulls.
def sesh_with_large_data(prepared_schema_from_migrations_left): | ||
engine, script = prepared_schema_from_migrations_left | ||
sesh = sessionmaker(bind=engine)() | ||
insert_crmp_data(sesh) |
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.
If you omit this you will have a clean empty database. That's probably desirable for this test.
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.
so remove this entire function from conftest.py
?
|
||
# Check that data has been modified to remove nulls | ||
result = engine.execute( | ||
f"SELECT * FROM {schema_name}.meta_vars" |
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.
To make comparisons simpler (see below), specify the columns explicitly here.
result = engine.execute( | ||
f"SELECT * FROM {schema_name}.meta_vars" | ||
) | ||
for row in result: |
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.
If the database starts out empty, you can assume that only the one row you inserted comes back. Try
row = next(result)
instead of the for loop.
And then you can check assert row == (....)
where the parens are a tuple.
engine.execute( | ||
f"INSERT INTO {schema_name}.meta_vars(vars_id, cell_method, standard_name, display_name)" | ||
f"VALUES (10000, 'foo: bar', 'foo_bar', 'foo bar')" | ||
) |
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.
👍
result = engine.execute( | ||
f"SELECT * FROM {schema_name}.meta_vars" | ||
) | ||
for row in result: |
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.
See comments for test_upgrade.
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.
Looks great, @helfy18 ! Ready to merge!
) | ||
|
||
row = next(result) | ||
assert row == (1, "foo: bar", "foo_bar", "foo bar") |
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.
👍
) | ||
|
||
row = next(result) | ||
assert row == (10000, None, None, None) |
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.
👍
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.
Approved!
Resolves #29
Add not null constraints to meta_vars.