Skip to content

Commit

Permalink
Merge pull request #870 from MolSSI/task_queue_idx
Browse files Browse the repository at this point in the history
Small task queue fix & migration code location
  • Loading branch information
bennybp authored Dec 19, 2024
2 parents 5eb8015 + 9beb648 commit 700e30d
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,17 @@
"""

import json
from hashlib import sha256

import sqlalchemy as sa
from alembic import op

from qcportal.serialization import _JSONEncoder

# revision identifiers, used by Alembic.
revision = "981f69781d65"
down_revision = "148fef89c2ec"
branch_labels = None
depends_on = None


def hash_dict(d):
j = json.dumps(d, ensure_ascii=True, sort_keys=True, cls=_JSONEncoder).encode("utf-8")
return sha256(j).hexdigest()
from migration_helpers.hashing import hash_dict_1


def create_hashes(table):
Expand All @@ -32,7 +25,7 @@ def create_hashes(table):
all_kw = res.fetchall()

for spec_id, kw in all_kw:
h = hash_dict(kw)
h = hash_dict_1(kw)
op.execute(sa.text(f"""UPDATE {table} SET keywords_hash = '{h}' WHERE id = {spec_id};"""))


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"""Fix task queue sort
Revision ID: 8263992eb6c8
Revises: f8a7c273f18a
Create Date: 2024-12-18 11:34:57.186942
"""

from alembic import op

# revision identifiers, used by Alembic.
revision = "8263992eb6c8"
down_revision = "f8a7c273f18a"
branch_labels = None
depends_on = None


def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_index("ix_task_queue_sort", table_name="task_queue")
op.execute(
"CREATE INDEX ix_task_queue_sort ON task_queue (priority DESC, sort_date, id, tag) WHERE available = True;"
)
# ### end Alembic commands ###


def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
pass
# ### end Alembic commands ###
48 changes: 48 additions & 0 deletions qcfractal/qcfractal/alembic/versions/migration_helpers/hashing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import base64
import json
from hashlib import sha256
from typing import Any

import numpy as np

try:
from pydantic.v1 import BaseModel
from pydantic.v1.json import pydantic_encoder
except ImportError:
from pydantic import BaseModel
from pydantic.json import pydantic_encoder


class _JSONEncoder_1(json.JSONEncoder):
def default(self, obj: Any) -> Any:
# JSON does not handle byte arrays
# So convert to base64
if isinstance(obj, bytes):
return {"_bytes_base64_": base64.b64encode(obj).decode("ascii")}

# Now do anything with pydantic, excluding unset fields
# Also always use aliases when serializing
if isinstance(obj, BaseModel):
return obj.dict(exclude_unset=True, by_alias=True)

# Let pydantic handle other things
try:
return pydantic_encoder(obj)
except TypeError:
pass

# Flatten numpy arrays
# This is mostly for Molecule class
# TODO - remove once all data in the database in converted
if isinstance(obj, np.ndarray):
if obj.shape:
return obj.ravel().tolist()
else:
return obj.tolist()

return json.JSONEncoder.default(self, obj)


def hash_dict_1(d):
j = json.dumps(d, ensure_ascii=True, sort_keys=True, cls=_JSONEncoder_1).encode("utf-8")
return sha256(j).hexdigest()
4 changes: 3 additions & 1 deletion qcfractal/qcfractal/components/tasks/db_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ class TaskQueueORM(BaseORM):
__table_args__ = (
Index("ix_task_queue_tag", "tag"),
Index("ix_task_queue_required_programs", "required_programs", postgresql_using="gin"),
Index("ix_task_queue_sort", priority.desc(), sort_date.asc(), id.asc(), tag),
Index(
"ix_task_queue_sort", priority.desc(), sort_date.asc(), id.asc(), tag, postgresql_where=(available == True)
),
UniqueConstraint("record_id", name="ux_task_queue_record_id"),
# WARNING - these are not autodetected by alembic
CheckConstraint(
Expand Down

0 comments on commit 700e30d

Please sign in to comment.