-
Notifications
You must be signed in to change notification settings - Fork 0
/
info.py
125 lines (119 loc) · 5.54 KB
/
info.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# autopep8: off
import sys; sys.dont_write_bytecode = True
# autopep8: on
import locale
from pymongo import MongoClient
from backend.get_field_paths import parse_nested_objs
from cli.info_cli import (add_args_ru,
add_args_en)
__version__ = 'v5.6'
__authors__ = ['Platon Bykadorov ([email protected]), 2020-2022']
def conv_data_measure(size):
'''
Функция конвертирует байты в такую единицу
измерения, чтобы значение получалось
наиболее компактным/читабельным.
'''
if size < 1000:
return f'{size} B'
elif size < 1000000:
return f'{round(size/1000, 1)} KB'
elif size < 1000000000:
return f'{round(size/1000000, 1)} MB'
elif size < 1000000000000:
return f'{round(size/1000000000, 1)} GB'
else:
return f'{round(size/1000000000000, 1)} TB'
# CLI.
if locale.getdefaultlocale()[0][:2] == 'ru':
args = add_args_ru(__version__,
__authors__)
else:
args = add_args_en(__version__,
__authors__)
# Если исследователь не задал ни одного аргумента,
# выведутся имена всех имеющихся на компе MongoDB-баз.
# Если же он указал имя конкретной базы, появятся
# её характеристики. Выведутся как общие сведения
# о БД, так и описания некоторых составляющих её
# коллекций с примерами документов. Некоторых -
# потому что, как правило, для понимания устройства
# базы, достаточно заглянуть в пару-тройку коллекций.
client = MongoClient()
if args.src_db_name is None:
all_db_names = sorted(client.list_database_names())
print('\nNames of all MongoDB databases:',
f'\n{", ".join(all_db_names)}')
else:
src_db_name = args.src_db_name
src_db_obj = client[src_db_name]
src_coll_names = sorted(src_db_obj.list_collection_names())
src_colls_quan = len(src_coll_names)
src_db_stats = src_db_obj.command('dbstats')
src_db_storagesize = conv_data_measure(src_db_stats['storageSize'])
src_db_indexsize = conv_data_measure(src_db_stats['indexSize'])
src_db_totalsize = conv_data_measure(src_db_stats['totalSize'])
src_coll_ext = src_coll_names[0].rsplit('.', maxsplit=1)[1]
if args.colls_quan_limit == 0 or args.colls_quan_limit > src_colls_quan:
colls_quan_limit = src_colls_quan
else:
colls_quan_limit = args.colls_quan_limit
print(f'\nCharacteristics of {src_db_name} DB:')
print('\n\tQuantity of collections:',
f'\n\t{src_colls_quan}')
print('\n\tstorageSize:',
f'\n\t{src_db_storagesize}')
print('\n\tindexSize:',
f'\n\t{src_db_indexsize}')
print('\n\ttotalSize:',
f'\n\t{src_db_totalsize}')
print('\n\tQuasi-extension of collections:',
f'\n\t{src_coll_ext}')
if colls_quan_limit == src_colls_quan:
print('\n\tCharacteristics of all collections:')
elif colls_quan_limit == 1:
print('\n\tCharacteristics of the first collection:')
else:
print(f'\n\tCharacteristics of the first {colls_quan_limit} collections:')
docs_quan_limit = args.docs_quan_limit
for src_coll_index in range(colls_quan_limit):
src_coll_name = src_coll_names[src_coll_index]
src_coll_obj = src_db_obj[src_coll_name]
docs_quan = src_coll_obj.count_documents({})
src_coll_stats = src_db_obj.command('collstats', src_coll_name)
src_coll_storagesize = conv_data_measure(src_coll_stats['storageSize'])
src_coll_totalindexsize = conv_data_measure(src_coll_stats['totalIndexSize'])
src_coll_totalsize = conv_data_measure(src_coll_stats['totalSize'])
field_paths = parse_nested_objs(src_coll_obj.find_one({'meta': {'$exists': False}}))
ind_info = src_coll_obj.index_information()
ind_field_paths, ind_names = [], []
for ind_name, ind_details in ind_info.items():
for tup in ind_details['key']:
if tup[0] not in ind_field_paths:
ind_field_paths.append(tup[0])
ind_names.append(ind_name)
curs_obj = src_coll_obj.find(limit=docs_quan_limit)
print(f'\n\t\t{src_coll_name} collection:')
print('\n\t\t\tQuantity of documents:',
f'\n\t\t\t{docs_quan}')
print('\n\t\t\tstorageSize:',
f'\n\t\t\t{src_coll_storagesize}')
print('\n\t\t\ttotalIndexSize:',
f'\n\t\t\t{src_coll_totalindexsize}')
print('\n\t\t\ttotalSize:',
f'\n\t\t\t{src_coll_totalsize}')
print('\n\t\t\tPaths to fields of the second document:',
f'\n\t\t\t{", ".join(field_paths)}')
print('\n\t\t\tPaths to indexed fields:',
f'\n\t\t\t{", ".join(ind_field_paths)}')
print('\n\t\t\tNames of indexes:',
f'\n\t\t\t{", ".join(ind_names)}')
if docs_quan_limit == 0:
print('\n\t\t\tAll documents:')
elif docs_quan_limit == 1:
print('\n\t\t\tThe first document:')
else:
print(f'\n\t\t\tThe first {docs_quan_limit} documents:')
for doc in curs_obj:
print(f'\n\t\t\t\t{doc}')
client.close()