def rb_post(): """ Создание нового справочника :return: """ j = flask.request.get_json() rb = RefBookRegistry.create(j) return rb.meta
def migrate_from_v1(): def blocks(iterable, max_size=2000): result = [] i = 0 for item in iterable: result.append(item) i += 1 if i >= max_size: yield result result = [] i = 0 if result: yield result def get_field_codes(collection): codes = set() for row in collection.find(): codes |= set(row.keys()) codes.discard('_id') return codes parser = argparse.ArgumentParser() parser.add_argument('--all', action='store_const', const=True, default=False) parser.add_argument('--host', default=None) parser.add_argument('--port', default=None) parser.add_argument('--from-db', default='vesta') parser.add_argument('--db', default=nvesta_db) args = parser.parse_args(sys.argv[1:]) mongo = pymongo.MongoClient( host=args.host, port=args.port, ) RefBookRegistry.bootstrap(mongo[args.db]) db_vesta = mongo[args.from_db] RefBookRegistry.bootstrap(mongo[args.db]) processed_dicts = {'dict_names'} processed_dicts.update(set(RefBookRegistry.names())) for v_description in db_vesta['dict_names'].find(): code = v_description.get('code') if code in processed_dicts: continue v_collection = db_vesta[code] count = v_collection.count() print 'Transferring', str(count).rjust(6), code primary_link = None linked = v_description.get('linked') if linked: primary_link = { 'left_field': linked['origin_field'], 'right_field': linked['linked_field'], 'right_rb': linked['collection']['code'], } rb = RefBookRegistry.create({ 'code': code, 'name': v_description.get('name') or code, 'description': v_description.get('description'), 'oid': v_description.get('oid'), 'fields': [{ 'key': fc, 'mandatory': fc == 'code', } for fc in sorted(get_field_codes(v_collection))], 'primary_link': primary_link, 'version': safe_traverse(v_description, 'version', 'version', default=None) }) for block in blocks(v_collection.find()): rb.save_bulk(rb.record_factory(raw) for raw in block) processed_dicts.add(code) for code in db_vesta.collection_names(False): if code in processed_dicts: continue v_collection = db_vesta[code] count = v_collection.count() print 'Transferring', str(count).rjust(6), code rb = RefBookRegistry.create({ 'code': code, 'name': code, 'description': '', 'oid': '', 'fields': [{ 'key': fc, 'mandatory': fc == 'code', } for fc in sorted(get_field_codes(v_collection))], 'primary_link': None, }) for block in blocks(v_collection.find()): rb.save_bulk(rb.record_factory(raw) for raw in block) RefBookRegistry.bootstrap(mongo[args.db])
def import_nsi_dict(nsi_dict, nsi_client): code = nsi_dict['code'] name = nsi_dict['name'] with log_context(['nsi', 'import']) as log: log.log(u'Импорт {0} ({1})'.format(name, code)) log.tags.add(code) try: # Пытаемся понять, какая версия справочника нынче актуальна latest_version = prepare_dictionary( nsi_client.getVersionList(code)[-1]) latest_version['date'] = datetime.strptime(latest_version['date'], '%d.%m.%Y') except (IndexError, ValueError), e: # Не получилось. С позором ретируемся. log.tags.add('import error') log.error(u'Ошибка получения версии ({0}): {1}'.format(code, e)) return try: # Есть два варианта: либо справочник есть... rb = RefBookRegistry.get(code) except KeyError: # ...либо его надо создать. rb = RefBookRegistry.create({ 'code': nsi_dict.get('code', nsi_dict.get('id')), 'name': nsi_dict.get('name', nsi_dict.get('code', nsi_dict.get('id'))), 'description': nsi_dict.get('description'), 'oid': nsi_dict.get('oid'), }) my_version = rb.meta.version their_version = latest_version['version'] def dump_documents(docs): log.log(u'Начинаем обновление данных...') documents = map(prepare_dictionary, docs) log.log(u'Новых/изменённых записей: %s' % len(documents)) # Сперва меняем (при необходимости) структуру справочника names = set() for doc in documents: names.update(set(doc.iterkeys())) own_names = set(field.key for field in rb.meta.fields) new_names = names - own_names all_names = names | own_names if new_names: # Новые столбцы появились, надо добавить log.log(u'Структура справочника изменилась. Решейпим...') for key in new_names: rb.meta.fields.append(FieldMeta(key=key)) rb.meta.reshape() key_names = (key for key in ('identcode', 'code', 'id', 'recid', 'oid') if key in all_names) for key in key_names: rb.collection.create_index(key, sparse=True) log.log(u'Добавляем/обновляем записи...') documents_to_save = [] for doc in documents: existing = None for key in key_names: if key in doc: existing = rb.find_one({key: doc[key]}) if existing: # Нечего по сто тыщ раз искать одно и то же break if not existing: existing = rb.record_factory() existing.update(doc) documents_to_save.append(existing) log.log(u'Сбрасываем записи в БД...') rb.save_bulk(documents_to_save) if not my_version: log.log(u'Локальный справочник не имеет версии, создаётся') parts_number = nsi_client.get_parts_number(code, their_version) log.log(u'Ответ получен. Всего частей: %s' % parts_number) for i in xrange(parts_number or 0): log.log(u'Запрашиваем часть %s / %s' % (i + 1, parts_number)) request_result = nsi_client.get_parts_data( code, their_version, i + 1) log.log(u'Ответ получен. Разбираем...') dump_documents(doc for doc in request_result if doc) log.log(u'Разобрано') elif my_version and my_version != their_version: log.log(u'Локальная версия справочника: {0}'.format(my_version)) log.log( u'Актуальная версия справочника: {0}'.format(their_version)) log.log(u'Версии не совпадают, обновляем diff...') request_result = nsi_client.getRefbookUpdate( code=code, user_version=my_version) log.log(u'Ответ получен. Разбираем...') dump_documents(doc for doc in request_result if doc) log.log(u'Разобрано') else: log.log(u'Локальная версия справочника: {0}'.format(my_version)) log.log( u'Актуальная версия справочника: {0}'.format(their_version)) log.log(u'Версии совпадают, не обновляем справочник') return