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

add management command too update collections #28

Merged
merged 1 commit into from
Oct 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions django_typesense/collections.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import pdb

import django
import logging

from typing import Iterable, Union, Dict, List

Expand All @@ -16,6 +15,8 @@
from django_typesense.fields import TypesenseField, TypesenseCharField
from django_typesense.typesense_client import client

logger = logging.getLogger(__name__)

_COLLECTION_META_OPTIONS = {
'schema_name', 'default_sorting_field', 'token_separators', 'symbols_to_index', 'query_by_fields'
}
Expand Down Expand Up @@ -196,9 +197,14 @@ def update_typesense_collection(self):
"""
Update the schema of an existing collection
"""
try:
current_schema = self.retrieve_typesense_collection()
except ObjectNotFound:
self.create_typesense_collection()
current_schema = self.retrieve_typesense_collection()

self.create_or_update_synonyms()

current_schema = self.retrieve_typesense_collection()
schema_changes = {}
field_changes = []

Expand All @@ -222,6 +228,7 @@ def update_typesense_collection(self):
schema_changes['fields'] = field_changes

if not schema_changes:
logger.debug(f"No schema changes in {self.schema_name}")
return

return client.collections[self.schema_name].update(schema_changes)
Expand Down Expand Up @@ -272,16 +279,25 @@ def create_or_update_synonyms(self):
defined_synonyms.update(synonym_data)

missing_synonyms_names = set(current_synonyms.keys()).difference(defined_synonyms.keys())
has_changes = False

for synonym_name in missing_synonyms_names:
has_changes = True
self.delete_synonym(synonym_name)

for synonym_name, synonym_data in defined_synonyms.items():
if synonym_name not in current_synonyms:
has_changes = True
client.collections[self.schema_name].synonyms.upsert(synonym_name, synonym_data)
elif synonym_data != current_synonyms[synonym_name]:
has_changes = True
client.collections[self.schema_name].synonyms.upsert(synonym_name, synonym_data)

if has_changes:
logger.debug(f"Synonyms updated in {self.schema_name}")
else:
logger.debug(f"No synonyms to update in {self.schema_name}")

def get_synonyms(self) -> dict:
"""List all synonyms associated with this collection"""
return client.collections[self.schema_name].synonyms.retrieve()
Expand Down
Empty file.
Empty file.
45 changes: 45 additions & 0 deletions django_typesense/management/commands/updatecollections.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import sys

from django.core.management import BaseCommand
from django.apps import apps


class Command(BaseCommand):
help = "Create and/or Update Typesense Collections"

def add_arguments(self, parser):
parser.add_argument(
"args",
metavar="collection_name",
nargs="*",
help="Specify the collection schema name(s) to create or update.",
)

def handle(self, *collection_names, **options):
collections = {}
for model_data in apps.all_models.values():
for model in model_data.values():
if hasattr(model, 'collection_class'):
collections[model.collection_class.schema_name] = model.collection_class

collections_for_action = []
# Make sure the collection name(s) they asked for exists
if collection_names := set(collection_names):
has_bad_names = False

for collection_name in collection_names:
try:
collection = collections[collection_name]
except KeyError:
self.stderr.write(f"No collection exists with schema name '{collection_name}'")
has_bad_names = True
else:
collections_for_action.append(collection)

if has_bad_names:
sys.exit(2)
else:
collections_for_action = collections.values()

for collection in collections_for_action:
collection().update_typesense_collection()
Loading