Skip to content

Commit

Permalink
performance improvement
Browse files Browse the repository at this point in the history
  • Loading branch information
aleks-iv committed Jun 26, 2024
1 parent da49c16 commit 5eb4e01
Show file tree
Hide file tree
Showing 12 changed files with 140 additions and 86 deletions.
2 changes: 0 additions & 2 deletions ckanext/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# encoding: utf-8

# this is a namespace package
try:
import pkg_resources
Expand Down
16 changes: 10 additions & 6 deletions ckanext/relationship/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ def relationship_get_entity_list(entity, entity_type, include_private=True):
entity_list = entity_list["results"]
else:
entity_list = tk.get_action("relationship_get_entity_list")(
context, {"entity": entity, "entity_type": entity_type}
context,
{"entity": entity, "entity_type": entity_type},
)
entity_list = [
{"id": id, "name": name, "title": title} for id, name, title in entity_list
Expand Down Expand Up @@ -78,10 +79,12 @@ def relationship_get_selected_json(selected_ids: list = []) -> str:


def relationship_get_choices_for_related_entity_field(
field: dict[str, Any], current_entity_id: str | None
field: dict[str, Any],
current_entity_id: str | None,
) -> list[str | None]:
entities = relationship_get_entity_list(
field["related_entity"], field["related_entity_type"]
field["related_entity"],
field["related_entity_type"],
)

choices = []
Expand All @@ -91,7 +94,8 @@ def relationship_get_choices_for_related_entity_field(
continue

if field.get("updatable_only", False) and not tk.h.check_access(
field["related_entity"] + "_update", {"id": entity["id"]}
field["related_entity"] + "_update",
{"id": entity["id"]},
):
continue

Expand All @@ -118,6 +122,6 @@ def relationship_format_autocomplete(packages: dict[str, Any]) -> dict[str, Any]
"title": pkg["title"],
}
for pkg in packages
]
}
],
},
}
77 changes: 56 additions & 21 deletions ckanext/relationship/logic/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
from flask import jsonify
from sqlalchemy import or_

import ckan.logic as logic
import ckan.plugins.toolkit as tk
from ckan import authz
from ckan import authz, logic
from ckan.logic import validate
from ckan.types import Context, DataDict
from ckan.types import Action, Context, DataDict

import ckanext.relationship.logic.schema as schema
from ckanext.relationship import utils
from ckanext.relationship.logic import schema
from ckanext.relationship.model.relationship import Relationship
from ckanext.relationship.utils import entity_name_by_id

Expand All @@ -18,7 +18,8 @@

@validate(schema.relation_create)
def relationship_relation_create(
context: Context, data_dict: DataDict
context: Context,
data_dict: DataDict,
) -> list[dict[str, str]]:
"""Create relation with specified type (relation_type) between two entities
specified by ids (subject_id, object_id). Also create reverse relation."""
Expand All @@ -29,10 +30,12 @@ def relationship_relation_create(
relation_type = data_dict.get("relation_type")

if Relationship.by_object_id(subject_id, object_id, relation_type):
return
return None

relation = Relationship(
subject_id=subject_id, object_id=object_id, relation_type=relation_type
subject_id=subject_id,
object_id=object_id,
relation_type=relation_type,
)

reverse_relation = Relationship(
Expand All @@ -50,7 +53,8 @@ def relationship_relation_create(

@validate(schema.relation_delete)
def relationship_relation_delete(
context: Context, data_dict: DataDict
context: Context,
data_dict: DataDict,
) -> list[dict[str, str]]:
"""Delete relation with specified type (relation_type) between two entities
specified by ids (subject_id, object_id). Also delete reverse relation."""
Expand Down Expand Up @@ -100,7 +104,7 @@ def relationship_relation_delete(
if relation_type:
reverse_relation = reverse_relation.filter(
Relationship.relation_type
== Relationship.reverse_relation_type[relation_type]
== Relationship.reverse_relation_type[relation_type],
)

reverse_relation = reverse_relation.all()
Expand All @@ -113,11 +117,12 @@ def relationship_relation_delete(

@validate(schema.relations_list)
def relationship_relations_list(
context: Context, data_dict: DataDict
context: Context,
data_dict: DataDict,
) -> list[dict[str, str]]:
"""Return dicts list of relation of specified entity (object_entity, object_type)
related with specified type of relation (relation_type) with entity specified
by id (subject_id).
"""Return a list of dictionaries representing the relations of a specified entity
(object_entity, object_type) related to the specified type of relation
(relation_type) with an entity specified by its id (subject_id).
"""
tk.check_access("relationship_relations_list", context, data_dict)

Expand All @@ -130,7 +135,10 @@ def relationship_relations_list(
relation_type = data_dict.get("relation_type")

relations = Relationship.by_subject_id(
subject_id, object_entity, object_type, relation_type
subject_id,
object_entity,
object_type,
relation_type,
)
if not relations:
return []
Expand Down Expand Up @@ -159,21 +167,16 @@ def relationship_get_entity_list(context: Context, data_dict: DataDict) -> list[

entity = data_dict["entity"]
entity = entity if entity != "organization" else "group"

entity_type = data_dict["entity_type"]

entity_class = logic.model_name_to_class(model, entity)

entity_list = (
return (
context["session"]
.query(entity_class.id, entity_class.name, entity_class.title)
.filter(entity_class.state != "deleted")
.filter(entity_class.type == entity_type)
.filter(entity_class.type == data_dict["entity_type"])
.all()
)

return entity_list


@validate(schema.autocomplete)
def relationship_autocomplete(context: Context, data_dict: DataDict) -> DataDict:
Expand Down Expand Up @@ -210,3 +213,35 @@ def relationship_autocomplete(context: Context, data_dict: DataDict) -> DataDict
)

return jsonify(format_autocomplete_helper(packages))


@tk.chained_action
@tk.side_effect_free
def package_show(next_: Action, context: Context, data_dict: DataDict) -> DataDict:
result = next_(context, data_dict)
if "with_relationships" not in data_dict:
return result
pkg_id = result["id"]
pkg_type = result["type"]
relations_info = utils.get_relations_info(pkg_type)
for (
related_entity,
related_entity_type,
relation_type,
) in relations_info:
field = utils.get_relation_field(
pkg_type,
related_entity,
related_entity_type,
relation_type,
)
result[field["field_name"]] = tk.get_action("relationship_relations_list")(
context,
{
"subject_id": pkg_id,
"object_entity": related_entity,
"object_type": related_entity_type,
"relation_type": relation_type,
},
)
return result
10 changes: 8 additions & 2 deletions ckanext/relationship/logic/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ def validator(key, data, errors, context):
entity_id = data.get(("id",))

current_relations = get_current_relations(
entity_id, related_entity, related_entity_type, relation_type
entity_id,
related_entity,
related_entity_type,
relation_type,
)

selected_relations = get_selected_relations(data[key])
Expand All @@ -46,7 +49,10 @@ def validator(key, data, errors, context):


def get_current_relations(
entity_id, related_entity, related_entity_type, relation_type
entity_id,
related_entity,
related_entity_type,
relation_type,
):
if entity_id:
current_relations = tk.get_action("relationship_relations_list")(
Expand Down
8 changes: 2 additions & 6 deletions ckanext/relationship/migration/relationship/env.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-

from __future__ import with_statement

import os
from logging.config import fileConfig

Expand Down Expand Up @@ -48,7 +44,7 @@ def run_migrations_offline():
url=url,
target_metadata=target_metadata,
literal_binds=True,
version_table="{}_alembic_version".format(name),
version_table=f"{name}_alembic_version",
)

with context.begin_transaction():
Expand All @@ -72,7 +68,7 @@ def run_migrations_online():
context.configure(
connection=connection,
target_metadata=target_metadata,
version_table="{}_alembic_version".format(name),
version_table=f"{name}_alembic_version",
)

with context.begin_transaction():
Expand Down
15 changes: 9 additions & 6 deletions ckanext/relationship/model/relationship.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
from sqlalchemy import Column, Text, or_

import ckan.logic as logic
import ckan.model as model
from ckan import logic, model
from ckan.model.types import make_uuid

from .base import Base
Expand Down Expand Up @@ -53,7 +52,7 @@ def by_object_id(cls, subject_id, object_id, relation_type):
or_(
cls.subject_id == subject_id,
cls.subject_id == subject_name,
)
),
)
.filter(or_(cls.object_id == object_id, cls.object_id == object_name))
.filter(cls.relation_type == relation_type)
Expand All @@ -62,12 +61,16 @@ def by_object_id(cls, subject_id, object_id, relation_type):

@classmethod
def by_subject_id(
cls, subject_id, object_entity, object_type=None, relation_type=None
cls,
subject_id,
object_entity,
object_type=None,
relation_type=None,
):
subject_name = _entity_name_by_id(subject_id)

q = model.Session.query(cls).filter(
or_(cls.subject_id == subject_id, cls.subject_id == subject_name)
or_(cls.subject_id == subject_id, cls.subject_id == subject_name),
)

if object_entity:
Expand All @@ -76,7 +79,7 @@ def by_subject_id(
or_(
object_class.id == cls.object_id,
object_class.name == cls.object_id,
)
),
)

if object_type:
Expand Down
35 changes: 16 additions & 19 deletions ckanext/relationship/plugin.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import ckan.plugins as plugins
import ckan.plugins.toolkit as tk
from ckan import plugins
from ckan.lib.search import rebuild
from ckan.logic import NotFound

import ckanext.scheming.helpers as sch

import ckanext.relationship.utils as utils
from ckanext.relationship import utils


@tk.blanket.actions
Expand Down Expand Up @@ -41,12 +41,14 @@ def after_dataset_delete(self, context, pkg_dict):
subject_id = pkg_dict["id"]

relations_ids_list = tk.get_action("relationship_relations_ids_list")(
context, {"subject_id": subject_id}
context,
{"subject_id": subject_id},
)

for object_id in relations_ids_list:
tk.get_action("relationship_relation_delete")(
context, {"subject_id": subject_id, "object_id": object_id}
context,
{"subject_id": subject_id, "object_id": object_id},
)

try:
Expand Down Expand Up @@ -80,16 +82,18 @@ def before_dataset_index(self, pkg_dict):
if not relations_ids:
continue
field = utils.get_relation_field(
pkg_type, related_entity, related_entity_type, relation_type
pkg_type,
related_entity,
related_entity_type,
relation_type,
)
pkg_dict[f'vocab_{field["field_name"]}'] = relations_ids

del pkg_dict[field["field_name"]]
pkg_dict.pop(field["field_name"], None)

return pkg_dict

def after_dataset_show(self, context, pkg_dict):
pkg_id = pkg_dict["id"]
pkg_type = pkg_dict["type"]
relations_info = utils.get_relations_info(pkg_type)
for (
Expand All @@ -98,19 +102,12 @@ def after_dataset_show(self, context, pkg_dict):
relation_type,
) in relations_info:
field = utils.get_relation_field(
pkg_type, related_entity, related_entity_type, relation_type
)
pkg_dict[field["field_name"]] = tk.get_action(
"relationship_relations_ids_list"
)(
context,
{
"subject_id": pkg_id,
"object_entity": related_entity,
"object_type": related_entity_type,
"relation_type": relation_type,
},
pkg_type,
related_entity,
related_entity_type,
relation_type,
)
pkg_dict.pop(field["field_name"], None)


def _update_relations(context, pkg_dict):
Expand Down
2 changes: 1 addition & 1 deletion ckanext/relationship/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest


@pytest.fixture
@pytest.fixture()
def clean_db(reset_db, migrate_db_for, with_plugins):
reset_db()
migrate_db_for("relationship")
Loading

0 comments on commit 5eb4e01

Please sign in to comment.