-
Notifications
You must be signed in to change notification settings - Fork 30
Migration workflow 1.1x
# create stat cfg table
poetry run invenio db create# create the index
poetry run invenio index create -b rero_ils/modules/stats_cfg/mappings/v7/stats_cfg/stat_cfg-v0.0.1.json 'stats_cfg-stat_cfg-v0.0.1-20231121'from invenio_search import current_search, current_search_client
# create the aliases
current_search_client.indices.put_alias('stats_cfg-stat_cfg-v0.0.1-20231121', 'stats_cfg')
current_search_client.indices.put_alias('stats_cfg-stat_cfg-v0.0.1-20231121', 'stats_cfg-stat_cfg-v0.0.1')# update operation logs templates
[p for p in current_search.put_templates()]poetry run invenio rero es index update-mappingfrom invenio_search import current_search_client
def reindex(source, destination):
res = current_search_client.reindex(
body=dict(
source=dict(
index=source
),
dest=dict(
index=destination,
version_type='external_gte'
)
),
wait_for_completion=False
)
return res['task']
def index_in_new(indices):
tasks = []
body = {
"settings": {
"number_of_shards": "8",
"number_of_replicas": "1",
"max_result_window": "100000"
}}
for index_name in indices:
print(index_name)
new_index_name = f'{index_name}-new'
current_search_client.indices.create(new_index_name, body=body)
tasks.append(reindex(index_name, new_index_name))
return tasks
def remove_old(indices):
for index_name in indices:
current_search_client.indices.delete(index_name)
print(f'{index_name} has been deleted')
def rename_to_old(indices):
tasks = []
body = {
"settings": {
"number_of_shards": "8",
"number_of_replicas": "1",
"max_result_window": "100000"
}}
for index_name in indices:
print(index_name)
new_index_name = f'{index_name}-new'
current_search_client.indices.create(index_name, body=body)
tasks.append(reindex(new_index_name, index_name))
return tasks
# Execute one line after the other
# Get the list of the operation logs indices
indices = list(current_search_client.indices.get_alias('operation_logs').keys())
tasks = index_in_new(indices)
# Check for completion
[current_search_client.tasks.get(t).get('completed') for t in tasks]
remove_old(indices)
tasks = rename_to_old(indices)
[current_search_client.tasks.get(t).get('completed') for t in tasks]
remove_old([i+'-new' for i in indices])from invenio_access.models import Role, ActionRoles
from invenio_db import db
from rero_ils.modules.cli.fixtures import load_role_policies
r1 = [r for r in Role.query.all()][-1]
r1.name
r1.name = 'pro_statistic_manager'
db.session.merge(r1)
db.session.commit()
cfg = {
"stat-access": [
"pro_statistic_manager",
],
"stat-search": [
"pro_statistic_manager",
"pro_library_administrator"
],
"stat-read": [
"pro_statistic_manager",
"pro_library_administrator"
],
"stat_cfg-access": [
"pro_full_permissions",
"pro_statistic_manager",
"pro_library_administrator"
],
"stat_cfg-search": [
"pro_full_permissions",
"pro_statistic_manager",
"pro_library_administrator"
],
"stat_cfg-read": [
"pro_full_permissions",
"pro_statistic_manager",
"pro_library_administrator"
],
"stat_cfg-create": [
"pro_full_permissions",
"pro_statistic_manager",
"pro_library_administrator"
],
"stat_cfg-update": [
"pro_full_permissions",
"pro_statistic_manager",
"pro_library_administrator"
],
"stat_cfg-delete": [
"pro_full_permissions",
"pro_statistic_manager",
"pro_library_administrator"
]}
load_role_policies(cfg)
# removes some roles
role_id = Role.query.filter_by(name='pro_read_only').first().id
ar = ActionRoles.query.filter_by(action='stat-search').filter_by(role_id=role_id).first()
db.session.delete(ar)
ar = ActionRoles.query.filter_by(action='stat-read').filter_by(role_id=role_id).first()
db.session.delete(ar)
db.session.commit()TODO
Entities: delete old index (new: local and remote with alias)
poetry run invenio index create -b rero_ils/modules/entities/remote_entities/mappings/v7/remote_entities/remote_entity-v0.0.1.json remote_entities-remote_entity-v0.0.1-20231031/_reindex
{
"source": {
"index": "entities-entity-v0.0.1-20230516"
},
"dest": {
"index": "remote_entities-remote_entity-v0.0.1-20231031",
"version_type": "external_gte"
},
"script": {
"source": "ctx._source['$schema'] = \"https://bib.rero.ch/schemas/remote_entities/remote_entity-v0.0.1.json\", "ctx._source['resource_type'] = \"remote\"]"
}
}
poetry run invenio rero es index update-mapping
#index_name=entities-entity-v0.0.1-20230516
#poetry run invenio index delete $index_name
poetry run invenio rero es alias put remote_entities-remote_entity-v0.0.1-20231031 remote_entities
poetry run invenio rero es alias put remote_entities-remote_entity-v0.0.1-20231031 remote_entities-remote_entity-v0.0.1
poetry run invenio rero es alias put remote_entities-remote_entity-v0.0.1-20231031 entities
poetry run invenio rero es alias put remote_entities-remote_entity-v0.0.1-20231031 entities-entity-v0.0.1
poetry run invenio index create -b rero_ils/modules/entities/local_entities/mappings/v7/local_entities/local_entity-v0.0.1.json local_entities-local_entity-v0.0.1-20231031
poetry run invenio rero es alias put local_entities-local_entity-v0.0.1-20231031 local_entities
poetry run invenio rero es alias put local_entities-local_entity-v0.0.1-20231031 local_entities-local_entity-v0.0.1
poetry run invenio rero es alias put local_entities-local_entity-v0.0.1-20231031 entities
poetry run invenio rero es alias put local_entities-local_entity-v0.0.1-20231031 entities-entity-v0.0.1
index_name=`poetry run invenio rero es index info -i items`
echo $index_name
poetry run invenio rero es index move items $index_name items-item-v0.0.1-20231019
poetry run invenio index delete $index_name
poetry run invenio rero es index update-mappingsu - postgres
psql reroils
ALTER TABLE entity_id RENAME TO remote_entity_id;
ALTER TABLE entity_metadata RENAME TO remote_entity_metadata;
from invenio_db import db
from invenio_pidstore.models import PersistentIdentifier, PIDStatus
PersistentIdentifier.query.filter_by(pid_type='ent').update({'pid_type': 'rement'})
db.session.commit()from sqlalchemy import func
from rero_ils.modules.entities.remote_entities.api import RemoteEntity
from invenio_db import db
# Correct $schema for entities in db
old_schema = 'https://bib.rero.ch/schemas/entities/entity-v0.0.1.json'
schema = 'https://bib.rero.ch/schemas/remote_entities/remote_entity-v0.0.1.json'
count = RemoteEntity.model_cls.query.filter(RemoteEntity.model_cls.json['$schema'].as_string() == old_schema).update({"json": func.jsonb_set(RemoteEntity.model_cls.json, '{$schema}', f'"{schema}"')}, synchronize_session=False)
db.session.commit()
print(f"{count} updated entities")If DB ES differences:
poetry run /network/nfs/data_ils/ils/scripts/correct_wrong_pids.py reroils utils correct-wrong-pids -t rement -v -cpoetry run invenio db createfrom rero_invenio_base.modules.tasks import run_on_worker
from rero_invenio_base.modules.utils import chunk
from rero_ils.modules.documents.api import Document
code = '''
def reindex(_ids):
from rero_ils.modules.documents.api import Document
n = 0
errors = []
for _id in _ids:
try:
doc = Document.get_record(_id)
doc.reindex()
n += 1
except Exception as e:
print('error', e)
errors.append(_id)
return (n, errors)
'''
parallel = 7
count = 0
for c in chunk([str(val) for val in Document.get_all_ids()], Document.count() // parallel):
count += 1
res = run_on_worker.delay(code, 'reindex', c)
print(count, len(c), res)Re-generate incorrect circulation stats
TO-DO: FIX script for pricing stats, the incorrect numbers are computed since those stats seem to have no date_range!!!
import arrow
from dateutil.relativedelta import relativedelta
from datetime import datetime
from rero_ils.modules.stats.api.librarian import StatsForLibrarian
from rero_ils.modules.stats.api.pricing import StatsForPricing
from rero_ils.modules.stats.api.api import Stat, StatsSearch
from rero_ils.modules.libraries.api import LibrariesSearch
search = StatsSearch()\
.filter('range', _created={'gte': '2023-07-30'})
for hit in list(search.source('pid').scan()):
try:
stat = Stat.get_record(hit.meta.id)
if stat['type'] == 'billing':
to_date = arrow.Arrow.fromdatetime(stat.created - relativedelta(days=1))
compute = StatsForPricing(to_date=to_date)
for val in stat.get('values', []):
lib_pid = val['library']['pid']
# number_of_checkouts
new_number_of_checkouts = compute.number_of_circ_operations(lib_pid, 'checkout')
print(lib_pid, val['number_of_checkouts'], new_number_of_checkouts)
val['number_of_checkouts'] = new_number_of_checkouts
# number_of_renewals
new_number_of_renewals = compute.number_of_circ_operations(lib_pid, 'extend')
print(lib_pid, val['number_of_renewals'], new_number_of_renewals)
val['number_of_renewals'] = new_number_of_renewals
# number_of_checkins
new_number_of_checkins = compute.number_of_circ_operations(lib_pid, 'checkin')
print(lib_pid, val['number_of_checkins'], new_number_of_checkins)
val['number_of_checkins'] = new_number_of_checkins
# number_of_ill_requests
new_number_of_ill_requests = compute.number_of_ill_requests(lib_pid, ['denied'])
print(lib_pid, val['number_of_validated_ill_requests'], new_number_of_ill_requests)
val.pop('number_of_validated_ill_requests')
val['number_of_ill_requests'] = new_number_of_ill_requests
# number_of_requests
new_number_of_requests = compute.number_of_circ_operations(lib_pid, 'request')
print(lib_pid, val['number_of_requests'], new_number_of_requests)
val['number_of_requests'] = new_number_of_requests
elif stat['type'] == 'librarian':
compute = StatsForLibrarian()
compute.date_range = stat['date_range']
for val in stat.get('values', []):
lib_pid = val['library']['pid']
# checkouts_for_transaction_library
new_checkouts_for_transaction_library = compute.checkouts_for_transaction_library(lib_pid)
print(lib_pid, val['checkouts_for_transaction_library'], new_checkouts_for_transaction_library)
val['checkouts_for_transaction_library'] = new_checkouts_for_transaction_library
# checkouts_for_owning_library
new_checkouts_for_owning_library = compute.checkouts_for_owning_library(lib_pid)
print(lib_pid, val['checkouts_for_owning_library'], new_checkouts_for_owning_library)
val['checkouts_for_owning_library'] = new_checkouts_for_owning_library
# active_patrons_by_postal_code
new_active_patrons_by_postal_code = compute.active_patrons_by_postal_code(lib_pid)
print(lib_pid, val['active_patrons_by_postal_code'], new_active_patrons_by_postal_code)
val['active_patrons_by_postal_code'] = new_active_patrons_by_postal_code
# new_active_patrons_by_postal_code
new_new_active_patrons_by_postal_code = compute.active_patrons_by_postal_code(lib_pid, new_patrons=True)
print(lib_pid, val['new_active_patrons_by_postal_code'], new_new_active_patrons_by_postal_code)
val['new_active_patrons_by_postal_code'] = new_new_active_patrons_by_postal_code
# renewals
new_renewals = compute.renewals(lib_pid)
print(lib_pid, val['renewals'], new_renewals)
val['renewals'] = new_renewals
# loans_of_transaction_library_by_item_location
new_loans_of_transaction_library_by_item_location = compute.loans_of_transaction_library_by_item_location(lib_pid)
print(lib_pid, val['loans_of_transaction_library_by_item_location'], new_loans_of_transaction_library_by_item_location)
val['loans_of_transaction_library_by_item_location'] = new_loans_of_transaction_library_by_item_location
stat.update(stat, commit=True, dbcommit=True, reindex=True)
except Exception as err:
print('ERROR', hit.pid, err)RERO+ instance: disable all local entities permissions for all_permissions role AND pro_entity_manager. We don't use this feature.
poetry run invenio rero es index update-mapping
index_name=`poetry run invenio rero es index info -i libraries`
echo $index_name
poetry run invenio rero es index move libraries $index_name libraries-library-v0.0.1-20230719
poetry run invenio rero es index update-mapping
poetry run invenio index delete $index_namepoetry run invenio alembic upgrade e63e5dfa2416poetry run invenio alembic upgrade 64a5cc96f96epoetry run invenio alembic upgrade 8d97be2c8ad6
from rero_ils.modules.stats.api import StatsForLibrarian, Stat
stat = Stat.get_record_by_pid('786')
compute = StatsForLibrarian()
compute.date_range = stat['date_range']
for val in stat.get('values', []):
lib_pid = val['library']['pid']
new_v_req = compute.validated_requests(lib_pid)
print(lib_pid, val['validated_requests'], new_v_req)
val['validated_requests'] = new_v_req
stat.update(stat, commit=True, dbcommit=True, reindex=True)- copy configuration for serial acquisition settings from acquisition settings and set default times for exception dates that are open and don't have times: the script below
from rero_ils.modules.libraries.api import Library, LibrariesSearch
print('Updating libraries acquisition settings and exception dates...')
libraries = LibrariesSearch()
print(f'Found {libraries.count()}')
errors = []
default_time_libs = []
time = {
'start_time': '08:00',
'end_time': '08:10'
}
for hit in libraries.source().scan():
lib = Library.get_record(hit.meta.id)
default_time = False
for date in lib.get('exception_dates', []):
if date.get('is_open', False) and not date.get('times', []):
default_time = True
date['times'] = [time]
if default_time:
default_time_libs.append(lib.pid)
try:
if settings := lib.get('acquisition_settings'):
lib['serial_acquisition_settings'] = settings
lib.update(lib, True, True, True)
print(f"Updating library, pid: {lib.get('pid')}.")
except Exception as err:
print(f"Error: {err} with lib pid: {lib.get('pid')}")
errors.append(lib.pid)
print(f"Libraries updated with {len(errors)} errors.")
print(errors)
print(f'Default times set for exception open days in libraries: {default_time_libs}')Write a script to add a default value for loan_status.
import click
from rero_ils.modules.ill_requests.api import ILLRequest, ILLRequestsSearch
click.secho('Updating ill_requests loan_status...')
ill_without_loan_status = ILLRequestsSearch().exclude('exists', field='loan_status')
click.secho(f'Found {ill_without_loan_status.count()} ill_requests without loan status')
status_mapping = {
"pending": "PENDING",
"validated": "ITEM_ON_LOAN",
"denied": "PENDING",
"closed": "ITEM_RETURNED"
}
errors = []
for hit in ill_without_loan_status.source().scan():
ill = ILLRequest.get_record(hit.meta.id)
try:
status = ill.get("status")
ill['loan_status'] = status_mapping[status]
ill.update(ill, True, True, True)
click.secho(f"Updating ill_request, pid: {ill.get('pid')}.")
except Exception as err:
click.secho(f"Error: {err} with ill_requests pid: {ill.get('pid')}")
errors.append(ill.pid)
click.secho(f"Ill_requests updated with {len(errors)} errors.")
for pid in errors:
ILLRequest.get_record_by_pid(pid).delete(dbcommit=True, delindex=True)
print(pid)from rero_ils.schedulers import current_scheduler
current_scheduler.remove('replace-idby-subjects-imported')
current_scheduler.remove('replace-idby-contribution')
current_scheduler.remove('replace-idby-subjects')# update es mapping
poetry run invenio rero es index update-mapping
# rename contribution tables
poetry run invenio alembic upgrade a710021979fe
# move the contribution index into the entity index
poetry run invenio index create -b rero_ils/modules/entities/mappings/v7/entities/entity-v0.0.1.json 'entities-entity-v0.0.1-20230516'from invenio_search import current_search_client
current_search_client.indices.put_alias('entities-entity-v0.0.1-20230516', 'entities')
current_search_client.indices.put_alias('entities-entity-v0.0.1-20230516', 'entities-entity-v0.0.1')from invenio_db import db
from invenio_pidstore.models import PersistentIdentifier, PIDStatus
PersistentIdentifier.query.filter_by(pid_type='cont').update({'pid_type': 'ent'})
db.session.commit()Note: remove the contributions es alias
from sqlalchemy import func
from rero_ils.modules.entities.api import Entity
from invenio_db import db
# Correct $schema for entities in db
old_schema = 'https://bib.rero.ch/schemas/contributions/contribution-v0.0.1.json'
schema = 'https://bib.rero.ch/schemas/entities/entity-v0.0.1.json'
count = Entity.model_cls.query.filter(Entity.model_cls.json['$schema'].as_string() == old_schema).update({"json": func.jsonb_set(Entity.model_cls.json, '{$schema}', f'"{schema}"')}, synchronize_session=False)
db.session.commit()
print(f"{count} updated entities")poetry run invenio reroils index reindex -t ent
poetry run invenio reroils index run -c 7 -dpoetry run /network/nfs/data_ils/ils/scripts/entities.py reroils utils correct-templates -c -l <change_this_log_file>Verify template 2015 is correct. (No contribution with entities having only type!)
index_name=`poetry run invenio rero es index info -i documents`
echo $index_name
poetry run invenio rero es index move -v documents $index_name documents-document-v0.0.1-20230531
poetry run invenio index delete $index_namepoetry run python /network/nfs/data_ils/ils/scripts/entities.py reroils utils correct-documents -c -l <change_this_log_file>from rero_invenio_base.modules.tasks import run_on_worker
from rero_invenio_base.modules.utils import chunk
n = 1
with open('/network/nfs/data_ils/ils/scripts/entities.py') as f:
src = f.read()
for c in chunk([str(val) for val in Document.get_all_ids()], int(Document.count()/14.9)):
run_on_worker.delay(src, 'do_documents', ids=c, logfile=f'/network/nfs/data_ils/ils/logs/create-authorized-access-points-2023-05-28-{n}.log', commit=True)
n += 1
print(f'start {n}')from rero_ils.schedulers import current_scheduler
current_scheduler.remove('sync-agents')
from invenio_cache import current_cache
data = current_cache.get('timestamps')
data.pop('sync_agents')
current_cache.set(key='timestamps', value=data, timeout=0)poetry run invenio index delete contributions-contribution-v0.0.1-20230116- update the es mapping :
poetry run invenio rero es index update-mapping - add new 'pro_statistics_manager' role using CLI :
poetry run invenio roles create -d 'Professional: Statistics manager' pro_statistics_manager - ill request:
is_ill_pickupandill_pickup_name(new fields) -> There is a script alembic.
# fixes contributions alias by hand using elastic chrome extensions
# Note: not necessary done in the previous script poetry run invenio alembic upgrade add75cbcad66
poetry run invenio alembic upgrade e3eb396b39bb- item operation history: change type of
triggertokeyword(missing field definition). Reindexoperation_logs.
from invenio_search import current_search_client
def reindex(source, destination):
res = current_search_client.reindex(
body=dict(
source=dict(
index=source
),
dest=dict(
index=destination,
version_type='external_gte'
)
),
wait_for_completion=False
)
return res['task']
def index_in_new(indices):
tasks = []
body = {
"settings": {
"number_of_shards": "8",
"number_of_replicas": "1",
"max_result_window": "100000"
}}
for index_name in indices:
print(index_name)
new_index_name = f'{index_name}-new'
current_search_client.indices.create(new_index_name, body=body)
tasks.append(reindex(index_name, new_index_name))
return tasks
def remove_old(indices):
for index_name in indices:
current_search_client.indices.delete(index_name)
print(f'{index_name} has been deleted')
def rename_to_old(indices):
tasks = []
body = {
"settings": {
"number_of_shards": "8",
"number_of_replicas": "1",
"max_result_window": "100000"
}}
for index_name in indices:
print(index_name)
new_index_name = f'{index_name}-new'
current_search_client.indices.create(index_name, body=body)
tasks.append(reindex(new_index_name, index_name))
return tasks
# Execute one line after the other
# Get the list of the operation logs indices
indices = list(current_search_client.indices.get_alias('operation_logs').keys())
tasks = index_in_new(indices)
# Check for completion
[current_search_client.tasks.get(t).get('completed') for t in tasks]
remove_old(indices)
tasks = rename_to_old(indices)
[current_search_client.tasks.get(t).get('completed') for t in tasks]
remove_old([i+'-new' for i in indices])poetry run invenio rero es index update-mappingpoetry run invenio alembic upgradeIn case of error try
On the database: update alembic_version set version_num='eec683a446e5' where version_num='e655021de0de'; and update alembic_version set version_num='eec683a446e5' where version_num='8145a7cdef99';. This should be done first on a test server.
poetry run invenio alembic upgrade 5f0b086e4b82
poetry run invenio alembic upgrade 8145a7cdef99
poetry run invenio alembic stamp 8145a7cdef99poetry run invenio reroils fixtures import_role_policies data/role_policies.json
poetry run invenio reroils fixtures import_system_role_policies data/system_role_policies.jsonEasier with: https://github.com/rero/rero-invenio-base/pull/12 (poetry run pip install git+https://github.com/rerowep/rero-invenio-base.git@wep-es-tasks)
index_name=`poetry run invenio rero es index info -i acq_orders`
echo $index_name
poetry run invenio rero es index move acq_orders $index_name acq_orders-acq_order-v0.0.1-20230313
poetry run invenio index delete $index_nameindex_name=`poetry run invenio rero es index info -i items`
echo $index_name
poetry run invenio rero es index move items $index_name items-item-v0.0.1-20230313
poetry run invenio index delete $index_nameindex_name=`poetry run invenio rero es index info -i documents`
echo $index_name
poetry run invenio rero es index move documents $index_name documents-document-v0.0.1-20230313
poetry run invenio index delete $index_nameindex_name=`poetry run invenio rero es index info -i patrons`
echo $index_name
poetry run invenio rero es index move patrons $index_name patrons-patron-v0.0.1-20230313
poetry run invenio index delete $index_namefrom rero_ils.modules.loans.api import LoansSearch
from rero_ils.modules.items.api import Item
from rero_ils.modules.loans.models import LoanState
states = [
LoanState.PENDING,
LoanState.ITEM_AT_DESK,
LoanState.ITEM_IN_TRANSIT_FOR_PICKUP,
LoanState.ITEM_IN_TRANSIT_TO_HOUSE
]
item_requested_pids = set([hit.item_pid.value for hit in LoansSearch().filter('terms', state=states).source('item_pid').scan()])
for pid in item_requested_pids:
rec = Item.get_record_by_pid(pid)
rec.reindex()from rero_invenio_base.modules.tasks import run_on_worker
from rero_invenio_base.modules.utils import chunk
from rero_ils.modules.items.api import ItemsSearch
code = '''
def reindex(_ids):
from rero_ils.modules.items.api import Item
n = 0
errors = []
for _id in _ids:
try:
doc = Item.get_record(_id)
doc.reindex()
n += 1
except Exception as e:
print('error', e)
errors.append(_id)
return (n, errors)
'''
def get_all_ids():
search = ItemsSearch().filter('term', type='issue').source().scan()
for hit in search:
yield hit.meta.id
for c in chunk([str(val) for val in get_all_ids()], 500):
run_on_worker.delay(code, 'reindex', c)—— rero.ch | Twitter | Gitter —— RERO+ catalogue | RERO ILS test version | RERO DOC | RERO MEF ——