Skip to content
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

Create proper enums for job statuses #412

Merged
merged 27 commits into from
Oct 22, 2024

Conversation

michalkrzem
Copy link
Collaborator

@michalkrzem michalkrzem commented Oct 1, 2024

Your checklist for this pull request

  • I've read the contributing guideline.
  • I've tested my changes by building and running mquery, and testing changed functionality (if applicable)
  • I've added automated tests for my change (if applicable, optional)
  • I've updated documentation to reflect my change (if applicable)

What is the current behaviour?
Status column in Job model exists as a string

What is the new behaviour?
Status column in Job model is as a JobStatus enum.

@michalkrzem michalkrzem linked an issue Oct 1, 2024 that may be closed by this pull request
@msm-cert msm-cert changed the title 370 create proper enums for job statuses Create proper enums for job statuses Oct 2, 2024
@michalkrzem michalkrzem marked this pull request as ready for review October 2, 2024 14:11

def upgrade() -> None:
op.create_table(
Copy link
Member

Choose a reason for hiding this comment

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

Why this change? We should not change older migrations in any case. (Please also don't reformat them, to keep unnecessary git changes to minimum)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok. I understand. I did this because the alembic upgrade head command in an existing environment causes errors that the table exists. So I check beforehand if the table exists.


def upgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.create_table(
"jobagent",
Copy link
Member

Choose a reason for hiding this comment

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

similarly, please don't change and reformat this file

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ok

INSTALL.md Outdated
Comment on lines 23 to 24
docker compose exec web python3 -m mquery.db
docker compose exec web python3 -m alembic upgrade head
Copy link
Member

Choose a reason for hiding this comment

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

Not sure about this. We want to reduce the number of additional commands to zero (#402), not add more of them.

Copy link
Member

@msm-cert msm-cert Oct 2, 2024

Choose a reason for hiding this comment

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

If you don't want to fix this in this PR and want to work separately in #402, it's OK to leave it as it is now (i.e. don't change the documentation in this PR. It works for fresh installations, just doesn't run migrations automatically).

If you want, I'll add some hints to #402 how to approach it

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure about this. We want to reduce the number of additional commands to zero (#402), not add more of them.

All because of alembic, which does not automatically recognize the modification from varchar to enum. I am able to create an enum type in postgres from the model level, but alembic does not replace it (it still remains VARCHAR) - that's why my manual modifications in migration files.

I found a library https://pypi.org/project/alembic-postgresql-enum/, quite new, I have to test it, but the question is whether to enter something like that at all. Or maybe look for solutions in sqlalchemy dialects for postgresql

Copy link
Member

Choose a reason for hiding this comment

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

don't change the documentation. After #421 alembic will be run with web automatically anyway.


def upgrade() -> None:
op.execute(
"CREATE TYPE jobstatus AS ENUM ('done', 'new', 'cancelled', 'removed', 'processing');"
Copy link
Member

Choose a reason for hiding this comment

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

You don't need to know every possible type for this migration. Just change every value out of scope to cancelledand then convert to enum.

Copy link
Member

Choose a reason for hiding this comment

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

(But good point that we need to handle this correctly)

@msm-cert
Copy link
Member

msm-cert commented Oct 2, 2024

By the way, I've created an issue for removing the "removed" status. #414

It may be a good time to implement it (for you it's just a few lines of code now, but it'll require another migration if done separately). If that's OK, please also remove this status from code at this time.

INSTALL.md Outdated
Comment on lines 23 to 24
docker compose exec web python3 -m mquery.db
docker compose exec web python3 -m alembic upgrade head
Copy link
Member

Choose a reason for hiding this comment

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

don't change the documentation. After #421 alembic will be run with web automatically anyway.

INSTALL.md Outdated
@@ -39,6 +40,7 @@ cd mquery
vim .env
docker compose -f docker-compose.dev.yml up # this will take a while
docker compose exec dev-web python3 -m mquery.db
docker compose exec dev-web python3 -m alembic upgrade head
Copy link
Member

Choose a reason for hiding this comment

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

don't change the documentation. After #421 alembic will be run with web automatically anyway.

README.md Outdated
@@ -26,6 +26,7 @@ cd mquery
vim .env # optional - change samples and index directory locations
docker compose up --scale daemon=3 # building the images will take a while
docker compose exec web python3 -m mquery.db
docker compose exec web python3 -m alembic upgrade head
Copy link
Member

Choose a reason for hiding this comment

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

don't change the documentation. After #421 alembic will be run with web automatically anyway.

@@ -1,3 +1,4 @@
import alembic_postgresql_enum # noqa: ignore=F401
Copy link
Member

Choose a reason for hiding this comment

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

I am basically sure there is no need for a new dependency here.


def downgrade() -> None:
# ### commands auto generated by Alembic - please adjust! ###
op.sync_enum_values(
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't this drop the table instead?

Comment on lines 23 to 25
"ursadb_url",
sqlmodel.sql.sqltypes.AutoString(),
nullable=False,
Copy link
Member

Choose a reason for hiding this comment

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

ideally this line should not change (this PR is completely unrelated to this file). Is there anything wong with the previous formatting?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I had to modify this because black raise errors.

Comment on lines 17 to 31
def upgrade() -> None:
sa.Enum(
"done", "new", "cancelled", "removed", "processing", name="jobstatus"
).create(op.get_bind())
op.sync_enum_values(
"public",
"jobstatus",
["done", "new", "cancelled", "removed", "processing"],
[
TableReference(
table_schema="public", table_name="job", column_name="status"
)
],
enum_values_to_rename=[],
)
Copy link
Member

Choose a reason for hiding this comment

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

why two migrations for a single change?

Comment on lines 35 to 45
op.sync_enum_values(
"public",
"jobstatus",
["done", "new", "cancelled", "removed", "processing"],
[
TableReference(
table_schema="public", table_name="job", column_name="status"
)
],
enum_values_to_rename=[],
)
Copy link
Member

Choose a reason for hiding this comment

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

this should probably drop the table (downgrade)

@@ -1,3 +1,6 @@
import enum

from sqlalchemy import Enum as PgEnum
Copy link
Member

Choose a reason for hiding this comment

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

why not just Enum? If you want to rename it, DbEnum would be more appropriate

@@ -16,6 +15,7 @@ export const openidLoginUrl = (config) => {
if (config["openid_url"] === null || config["openid_client_id"] === null) {
// Defensive programming - config keys can be null.
return "#";
gi;
Copy link
Member

Choose a reason for hiding this comment

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

typo

Copy link
Member

Choose a reason for hiding this comment

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

still typo

src/db.py Outdated
@@ -87,7 +91,7 @@ def get_valid_jobs(self, username_filter: Optional[str]) -> List[Job]:
with self.session() as session:
query = (
select(Job)
.where(Job.status != "removed")
.where(Job.status != JobStatus.cancelled)
Copy link
Member

Choose a reason for hiding this comment

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

No need for this where - idea of #414 is to remove all jobs with this status from the database. So there are no more jobs that were removed and need to be filtered out.

Suggested change
.where(Job.status != JobStatus.cancelled)

src/db.py Outdated
Comment on lines 105 to 107
update(Job)
.where(Job.id == job)
.values(status=JobStatus.cancelled)
Copy link
Member

Choose a reason for hiding this comment

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

Again, the idea of #414 is to drop the jobs from the database. So this should be delete instead of update.



def upgrade() -> None:
op.execute("UPDATE job SET status = 'cancelled' WHERE status = 'removed';")
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
op.execute("UPDATE job SET status = 'cancelled' WHERE status = 'removed';")
op.execute("DELETE FROM job WHERE status = 'removed';")

actually this works too and is even better

# ### commands auto generated by Alembic - please adjust! ###
op.sync_enum_values(
"public",
"jobstatus",
Copy link
Member

Choose a reason for hiding this comment

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

actually I don't care about downgrates too much, and it's not even possible in this case. You can just raise NotImplementedError() here.

requirements.txt Outdated Show resolved Hide resolved
@michalkrzem michalkrzem requested a review from msm-cert October 18, 2024 07:17
@@ -16,6 +15,7 @@ export const openidLoginUrl = (config) => {
if (config["openid_url"] === null || config["openid_client_id"] === null) {
// Defensive programming - config keys can be null.
return "#";
gi;
Copy link
Member

Choose a reason for hiding this comment

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

still typo


# revision identifiers, used by Alembic.
revision = "f654d7e4fcc7"
down_revision = "6b495d5a4855"
Copy link
Member

Choose a reason for hiding this comment

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

The order of migrations is wrong. This will run after the attempted jobs removal.

I've tested it:

mquery-dev-web-1       | WARNING:  StatReload detected changes in 'tasks.py'. Reloading...
mquery-dev-web-1       | INFO:     Started server process [24]
mquery-dev-web-1       | INFO:     Waiting for application startup.
mquery-dev-web-1       | INFO  [alembic.runtime.migration] Context impl PostgresqlImpl.
mquery-dev-web-1       | INFO  [alembic.runtime.migration] Will assume transactional DDL.
mquery-dev-web-1       | INFO  [alembic.runtime.migration] Running upgrade dbb81bd4d47f -> 6b495d5a4855, add jobstatus
mquery-dev-web-1       | Revision ID: 6b495d5a4855
mquery-dev-web-1       | Revises: dbb81bd4d47f
mquery-dev-web-1       | Create Date: 2024-10-15 08:17:30.036531
mquery-postgres-1      | 2024-10-18 14:31:24.310 UTC [51] ERROR:  update or delete on table "job" violates foreign key constraint "match_job_id_fkey" on table "match"
mquery-postgres-1      | 2024-10-18 14:31:24.310 UTC [51] DETAIL:  Key (internal_id)=(34) is still referenced from table "match".
mquery-postgres-1      | 2024-10-18 14:31:24.310 UTC [51] STATEMENT:  DELETE FROM job WHERE status = 'removed';

Copy link
Member

Choose a reason for hiding this comment

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

Both migrations can be probably merged into one to fix this.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, yes, I forgot about this :/ So, one big migration file with create_foreign_key with ondelete="CASCADE", delete "removed" status, create jobstatus and alter table with new type?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, sounds good. A benefit of one big migration is that if something goes wrong then a rollback is performed (so the db is not stuck in an invalid state).

requirements.txt Outdated Show resolved Hide resolved
src/migrations/versions/6b495d5a4855_add_jobstatus.py Outdated Show resolved Hide resolved
src/migrations/versions/6b495d5a4855_add_jobstatus.py Outdated Show resolved Hide resolved
@msm-cert
Copy link
Member

(by the way, feel free to close resolved conversations)

@michalkrzem michalkrzem requested a review from msm-cert October 21, 2024 15:25
Copy link
Member

@msm-cert msm-cert left a comment

Choose a reason for hiding this comment

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

LGTM!

@msm-cert msm-cert merged commit c218523 into master Oct 22, 2024
10 checks passed
@msm-cert msm-cert deleted the 370-create-proper-enums-for-job-statuses branch October 22, 2024 22:16
This was referenced Oct 22, 2024
mickol34 pushed a commit that referenced this pull request Nov 6, 2024
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.

Create proper enums for Job statuses
2 participants