diff --git a/__pycache__/dm.cpython-36.pyc b/__pycache__/dm.cpython-36.pyc new file mode 100644 index 0000000..d41d1de Binary files /dev/null and b/__pycache__/dm.cpython-36.pyc differ diff --git a/db_template/tables.json b/db_template/dm.json similarity index 98% rename from db_template/tables.json rename to db_template/dm.json index 0931db0..251339d 100644 --- a/db_template/tables.json +++ b/db_template/dm.json @@ -7,7 +7,7 @@ { "fName": "id", "fDescription": "Номер п.п.", - "fType": "INT(6)", + "fType": "INTEGER", "index": "PRIMARY KEY", "autoIncrement": "yes", "relation": [] @@ -161,7 +161,7 @@ { "fName": "user", "fDescription": "Юзер шляпы", - "fType": "int(11)", + "fType": "INTEGER", "index": "no", "autoIncrement": "no", "relation": ["users.id", "last_name, name, middle_name"] @@ -191,7 +191,7 @@ { "fName": "user", "fDescription": "Юзер шляпы", - "fType": "int(11)", + "fType": "INTEGER", "index": "no", "autoIncrement": "no", "relation": ["users.id", "last_name, name, middle_name"] diff --git a/db_template/library.json b/db_template/library.json new file mode 100644 index 0000000..fcb18a3 --- /dev/null +++ b/db_template/library.json @@ -0,0 +1,141 @@ +{ + "tables": [ + { + "tableName": "publisher", + "tableDescription": "Издательство", + "fieldList": [ + { + "fName": "id", + "fDescription": "Номер п.п.", + "fType": "INTEGER", + "index": "PRIMARY KEY", + "autoIncrement": "yes", + "relation": [] + }, + { + "fName": "publisher_name", + "fDescription": "Наименование", + "fType": "char(20)", + "index": "no", + "autoIncrement": "no", + "relation": [] + } + ] + }, + { + "tableName": "authors", + "tableDescription": "Авторы", + "fieldList": [ + { + "fName": "id", + "fDescription": "Номер п.п.", + "fType": "INTEGER", + "index": "PRIMARY KEY", + "autoIncrement": "yes", + "relation": [] + }, + { + "fName": "last_name", + "fDescription": "Фамилия", + "fType": "char(20)", + "index": "no", + "autoIncrement": "no", + "relation": [] + }, + { + "fName": "name", + "fDescription": "Имя", + "fType": "char(20)", + "index": "no", + "autoIncrement": "no", + "relation": [] + }, + { + "fName": "middle_name", + "fDescription": "Отчество", + "fType": "char(20)", + "index": "no", + "autoIncrement": "no", + "relation": [] + } + ] + }, + { + "tableName": "books", + "tableDescription": "Книги", + "fieldList": [ + { + "fName": "id", + "fDescription": "Номер п.п.", + "fType": "INTEGER", + "index": "PRIMARY KEY", + "autoIncrement": "yes", + "relation": [] + }, + { + "fName": "book_name", + "fDescription": "Название", + "fType": "varchar(100)", + "index": "yes", + "autoIncrement": "no", + "relation": [] + }, + { + "fName": "description", + "fDescription": "Описание", + "fType": "varchar(200)", + "index": "no", + "autoIncrement": "no", + "relation": [] + }, + { + "fName": "authors_id", + "fDescription": "Автор", + "fType": "INTEGER", + "index": "no", + "autoIncrement": "no", + "relation": ["authors.id", "last_name, name, middle_name"] + }, + { + "fName": "publisher_id", + "fDescription": "Издательство", + "fType": "INTEGER", + "index": "no", + "autoIncrement": "no", + "relation": ["publisher.id", "publisher_name"] + }, + { + "fName": "category_id", + "fDescription": "Жанр", + "fType": "INTEGER", + "index": "no", + "autoIncrement": "no", + "relation": ["category.id", "category_name"] + } + + ] + }, + { + "tableName": "category", + "tableDescription": "Жанр", + "fieldList": [ + { + "fName": "id", + "fDescription": "Номер п.п.", + "fType": "INTEGER", + "index": "PRIMARY KEY", + "autoIncrement": "yes", + "relation": [] + }, + { + "fName": "category_name", + "fDescription": "Название жанра", + "fType": "varchar(100)", + "index": "yes", + "autoIncrement": "no", + "relation": [] + } + ] + } + ] +} diff --git a/dm.py b/dm.py index 544f131..d3ade4d 100644 --- a/dm.py +++ b/dm.py @@ -19,7 +19,7 @@ def firstInit(): cfg_file = os.path.join(cfg_dir, 'dm.cfg') # создадим файл конфигурации config.add_section('DataBase') - config.set('DataBase', 'db_type', 'mysql') + config.set('DataBase', 'db_type', 'sqlite') config.set('DataBase', 'db_hostname', 'localhost') config.set('DataBase', 'db_name', 'dm') config.set('DataBase', 'db_user', 'dm') @@ -30,7 +30,6 @@ def firstInit(): # Если конфиг уже есть читаем его если нет, создаем и потом читаем if os.path.isfile(cfg_file): - print('Read config -' + cfg_file) config.read(cfg_file) else: # Запись конфигурации в файл 'example.cfg' @@ -43,14 +42,13 @@ def firstInit(): template_dir = config.get('Directory', 'template_dir') db_type = config.get('DataBase', 'db_type') db_hostname = config.get('DataBase', 'db_hostname') - db_name = config.get('DataBase', 'db_name') - template_file = os.path.join(template_dir, "{}.json".format(db_name)) - if db_type == 'sqlite': - db_name = "{}.{}".format(os.path.join(work_dir, db_name), 'sqlite') - + db_name = os.path.join(work_dir, config.get('DataBase', 'db_name')) + else: + db_name = config.get('DataBase', 'db_name') db_user = config.get('DataBase', 'db_user') db_password = config.get('DataBase', 'db_password') + # Создаём нужные каталоги if os.path.isdir(work_dir): print(work_dir + " already exists") @@ -61,17 +59,17 @@ def firstInit(): else: os.mkdir(template_dir) # копируем и читаем файл шаблон БД - #print("template file "+ template_file) - #template_file = os.path.join(template_dir, 'tables.json') + template = config.get('DataBase', 'db_name') + '.json' + + template_file = os.path.join(template_dir, template) if os.path.isfile(template_file): - print("Template file " + template_file +" already exists") -# else: -# shutil.copy(template_file_name, template_file) + print("Template file already exists " + template_file) + else: + shutil.copy('db_template/dm.json', template_file) def dbConnect(): global c, db_type, db_hostname, db_user, db_password, db_name, conn - #print(db_name) if db_type == "mysql": import pymysql conn = pymysql.connect( @@ -150,15 +148,8 @@ def createTables(tbl_list): index = " PRIMARY KEY" else: index = '' - fieldType = tbl_list[i]["fieldList"][x]["fType"].lower() - #print(fieldType) - if fieldType[0:3] == 'int': - qwery_create = qwery_create + tbl_list[i]["fieldList"][x]["fName"] + ' ' + \ - 'INTEGER' + index + auto_increment - #print(fieldType) - else: - qwery_create = qwery_create + tbl_list[i]["fieldList"][x]["fName"] + ' ' + \ - tbl_list[i]["fieldList"][x]["fType"] + index + auto_increment + qwery_create = qwery_create + tbl_list[i]["fieldList"][x]["fName"] + ' ' + \ + tbl_list[i]["fieldList"][x]["fType"] + index + auto_increment field_names_list.append([tbl_list[i]["fieldList"][x]["fName"], tbl_list[i]["fieldList"][x]["fDescription"]]) # struct_fields_list.append(tbl_list[i]["fieldList"][x]["fName"]) @@ -184,7 +175,6 @@ def createTables(tbl_list): def initDBstructure(): global dbTablesDescriptionList, template_file, tblNamesList - #print(template_file) table_list = open(template_file, "r", encoding="utf-8") data = json.load(table_list, encoding="utf-8") tbl_list = data["tables"] @@ -220,18 +210,13 @@ def selectData(tbl): if db_type == "mysql": field_replace = field_replace.replace(",", ",' ',") - #subqwery = "(SELECT CONCAT(" + field_replace + ") FROM " + subqwery + " WHERE " + table1 + "." + field1 + "=" + tbl + "." + field + ") AS " + field - # subqwery = "(SELECT CONCAT({}) FROM {} WHERE {}.{}={}.{}) AS {}"\ - # .format(field_replace,subqwery,table1,field1,tbl,field,field) subqwery = "(SELECT CONCAT('>', {}.{}, '<', {}) FROM {} WHERE {}.{}={}.{}) AS {}"\ .format(tbl,field,field_replace,subqwery,table1,field1,tbl,field,field) elif db_type == "sqlite": field_replace = field_replace.replace(",", " || ' ' ||") - #subqwery = "(SELECT (" + field_replace + ") FROM " + subqwery +" WHERE "+ table1 + "." + field1 +"="+ tbl +"."+ field +") AS " + field subqwery = "(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}" \ .format(field_replace, subqwery, table1, field1, tbl, field, field) qwery = qwery.replace(field, subqwery) - #qwery = qwery.rstrip(',') + " FROM " + tbl + " LIMIT 10000" qwery = '{} FROM {} LIMIT 10000'.format(qwery.rstrip(','), tbl) print(qwery) c.execute(qwery) @@ -240,8 +225,6 @@ def selectData(tbl): # получаем на вход имя таблицы и возвращаем список заголовков полей def getTableStructure(tbl): global dbTablesDescriptionList, dbTablesStructList - #print(dbTablesDescriptionList) - #print(dbTablesStructList) for item in dbTablesDescriptionList: if item[0] == tbl: return item[1] @@ -249,8 +232,6 @@ def getTableStructure(tbl): # Получаем список названий полей и типов для заданной таблицы def getFields(tbl): global dbTablesDescriptionList, dbTablesStructList - #print(dbTablesDescriptionList) - #print(dbTablesStructList) for item in dbTablesStructList: if item[0] == tbl: #print(item[1]) @@ -270,7 +251,7 @@ def fieldTypeConvert(ftype): # разбираем строку на тип и длину ftype = str.lower(ftype) line = re.search("(.+?)\(([0-9]+)\)", ftype) - if line: + if line: fType = line.groups()[0] fLength = line.groups()[1] if fType == 'int' or fType == 'integer': @@ -279,26 +260,20 @@ def fieldTypeConvert(ftype): fType = 'character' else: fType = ftype + #print(fType) return fType def getFieldType(tbl, field): global dbTablesDescriptionList, dbTablesStructList - #print(dbTablesDescriptionList) - #print(dbTablesStructList) for item in dbTablesStructList: if item[0] == tbl: for i in item[1]: if i[0] == field: fType = i[1] return fType - #print(item[1]) - #return item[1] def getRelationsForField(tblSearch, fieldName): global dbTablesStructList, c, db_type - #print("Ищем связи для:" +tblSearch +','+ fieldName) - #print(dbTablesStructList) - #searchField = tblSearch + '.' + fieldName dataList = [] for item in dbTablesStructList: #print(item) @@ -309,16 +284,10 @@ def getRelationsForField(tblSearch, fieldName): if tblName == tblSearch: # выдергиваем из списка название и поле нужной нам таблицы if rel[0] == fieldName: - #print('table - ' + tblName) - ##print('field - ' + fieldName) - #print('relation - ' + str(rel)) l = rel[1][0].split('.') relTable = l[0] relField = l[1] replaceFields = rel[1][1] - # print('reltable - ' + relTable) - #print('relfield - ' + relField) - #print('relrelation - ' + replaceFields) return [relTable, relField, replaceFields] return "q" @@ -328,10 +297,6 @@ def insertDataIntoBD(dataList): global c, conn dbConnect() tableName = dataList[0] - #print(dataList) - #datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") - - #qwery = 'INSERT INTO ' + tableName + ' (' qwery = 'INSERT INTO {} ('.format(tableName) qweryData = '' qweryField = '' @@ -340,30 +305,23 @@ def insertDataIntoBD(dataList): #print(fType) # проверяем если значение поля пустое то в запрос оно не включается if item[1] != '': - #qweryField = qweryField + item[0] + ',' qweryField = '{}{},'.format(qweryField,item[0]) if fType == 'integer': - #qweryData = qweryData + '' + item[1] + ',' qweryData = '{}{},'.format(qweryData,item[1]) elif fType == 'datetime': # преобразуем дату всяко разно dt = datetime.strptime(item[1], "%d.%m.%y %H:%M") item[1] = str(dt) - #qweryData = qweryData + '\'' + item[1] + '\',' qweryData = "{}'{}',".format(qweryData,item[1]) elif fType == 'date': d = item[1].split('.') - #myDate = d[2] + '-' + d[1] + '-' + d[1] myDate = '{}-{}-{}'.format(d[2], d[1], d[1]) item[1] = str(myDate) - #qweryData = qweryData + '\'' + item[1] + '\',' qweryData = "{}'{}',".format(qweryData, item[1]) else: - #qweryData = qweryData + '\'' + item[1] + '\',' qweryData = "{}'{}',".format(qweryData, item[1]) - #qwery = qwery + qweryField.rstrip(',') + ')' + ' VALUES (' + qweryData.rstrip(',') + ');' qwery = '{}{}) VALUES ({});'.format(qwery, qweryField.rstrip(','), qweryData.rstrip(',')) print(qwery) @@ -399,18 +357,13 @@ def selectDataFromDB(tblName, fieldName, fieldValue): # составляем подзапрос и подменяем им поле в запросе if db_type == "mysql": fieldReplace = fieldReplace.replace(",", ",' ',") - #subqwery = "(SELECT CONCAT(" + fieldReplace + ") FROM " + subqwery + " WHERE " + table1 + "." + field1 + "=" + tblName + "." + field + ") AS " + field subqwery = '(SELECT CONCAT({}) FROM {} WHERE {}.{}={}.{}) AS {}'\ .format(fieldReplace, subqwery, table1, field1, tblName, field, field) elif db_type == "sqlite": fieldReplace = fieldReplace.replace(",", " || ' ' ||") - #subqwery = "(SELECT (" + fieldReplace + ") FROM " + subqwery +" WHERE "+ table1 + "." + field1 +"="+ tblName +"."+ field +") AS " + field subqwery = '(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}'\ .format(fieldReplace, subqwery, table1, field1, tblName, field, field) - #print("---" + subqwery) qwery = qwery.replace(field, subqwery) - #qwery = qwery.rstrip(',') + " FROM " + tblName + " LIMIT 10000" - #qwery = qwery.rstrip(',') + " FROM " + tblName + " WHERE " + fieldName + '=' + fieldValue qwery = '{} FROM {} WHERE {}={}'.format(qwery.rstrip(','), tblName, fieldName, fieldValue) @@ -500,9 +453,6 @@ def editDataIntoBD(dataList): qweryField = "{}'{}',".format(qweryField, item[1]) else: qweryField = "{}'{}',".format(qweryField, item[1]) - - - qwery = '{}{} WHERE {};'.format(qwery, qweryField.rstrip(','), qweryWhere) print(qwery) @@ -510,9 +460,18 @@ def editDataIntoBD(dataList): #conn.commit() #c.close() return +# Вывод структуры таблицы из базы данных +def getTableStructureFromDB(tableName): + global c, db_type, conn + + if db_type == 'sqlite': + qwery = 'PRAGMA table_info({})'.format(tableName) + fieldsList = c.execute(qwery).fetchall() + #for row in fieldsList: + # print(row) + return(fieldsList) #initDBstructure() firstInit() -print(template_file) dbConnect() diff --git a/gui.py b/gui.py index 6565d6b..b786248 100755 --- a/gui.py +++ b/gui.py @@ -404,7 +404,7 @@ def addDataIntoTable(dbTableName, tblDataWidget, data='NULL'): tblDataWidget.setItem(m, n, newitem) n += 1 m += 1 -# Показ менб и панели инструментов +# Показ меню и панели инструментов def showMenuToolbar(window): newAction = QAction(QIcon('img/new.gif'), 'Добавить', window) newAction.setShortcut('Ins') @@ -421,6 +421,11 @@ def showMenuToolbar(window): exitAction.setStatusTip('Выход') exitAction.triggered.connect(window.close) + structureAction = QAction(QIcon('img/table.gif'), 'Показать структуру', window) + #structureAction.setShortcut('Ctrl+Q') + structureAction.setStatusTip('Показать структуру') + structureAction.triggered.connect(showStructure) + cutAction = QAction(QIcon('img/cut.gif'), 'Вырезать', window) cutAction.setShortcut('Ctrl+X') cutAction.setStatusTip('Вырезать') @@ -436,7 +441,7 @@ def showMenuToolbar(window): pasteAction.setStatusTip('Вставить') # pasteAction.triggered.connect(window.close) - findAction = QAction(QIcon('img/find.gif'), 'Копировать', window) + findAction = QAction(QIcon('img/find.gif'), 'Поиск', window) findAction.setShortcut('Ctrl+F') findAction.setStatusTip('Искать') # findAction.triggered.connect(window.close) @@ -453,6 +458,7 @@ def showMenuToolbar(window): fileMenu.addAction(newAction) fileMenu.addAction(deleteAction) fileMenu.addAction(printAction) + fileMenu.addAction(structureAction) fileMenu.addAction(exitAction) editMenu = menubar.addMenu('&Редактирование') @@ -557,6 +563,19 @@ def editRecord(tableWidget, row, dbTableName, valueList): print(editForm.widgetsList) #dm.deleteRecordsFromDB(dbTableName, valueList) + +def showStructure(): + global tabRelationsData, listDBTables + tblDescr = listDBTables.model().data(listDBTables.currentIndex()) + i = 0 + for i in dbTablesList: + if i[1] == tblDescr: + tblName = i[0] + print(tblName) + #print(dm.getTableStructure(tblName)) + print(dm.getFields(tblName)) + print(dm.getTableStructureFromDB(tblName)) + def main(): global dbTablesList, listDBTables, tabRelationsData, dbFieldRelationValueList dbFieldRelationValueList = []