Compare commits
	
		
			10 Commits
		
	
	
		
			59b55c1e0f
			...
			3937be3cb5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 3937be3cb5 | ||
|   | 77da13fbaa | ||
|   | 8ca81184a9 | ||
|   | 7bcca92697 | ||
|   | 1e0950083e | ||
|   | 4efc72e071 | ||
|   | 9904d5b4e9 | ||
|   | 9cc5c6cd57 | ||
|   | c6a63b972e | ||
|   | b2de966586 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| .idea/ | ||||
| __pycache__/ | ||||
							
								
								
									
										42
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								README.md
									
									
									
									
									
								
							| @@ -1 +1,41 @@ | ||||
| Это зачаток программы управления данными на основе описания структуры в json формате. | ||||
| # Это зачаток программы управления данными на основе описания структуры в json формате. | ||||
| Пишется на python3 в качестве графической библиотеки Qt5. | ||||
|  | ||||
| # Использование | ||||
|  | ||||
| По умолчанию используется шаблон и БД 'dm'. Для того чтобы изменить БД, создаем JSON шаблон согласно описания (см. примеры в db_template). | ||||
|  | ||||
| Затем данный файл нужно скопировать в '~/.dm/db_template/', следущим шагом меняем в конфиге 'dm.cfg' имя БД на имя вашего шаблона без расширения json, т.е. к примеру для работы с книжным каталогом (файл db_template/library.json) файл настроек будет выглядеть следующим оюбразом:  | ||||
|  | ||||
| ``` | ||||
| [DataBase] | ||||
| db_type = sqlite | ||||
| db_hostname = localhost | ||||
| db_name = library | ||||
| db_user = dm | ||||
| db_password = password | ||||
|  | ||||
| [Directory] | ||||
| work_dir = /home/svkalinin/.dm | ||||
| template_dir = /home/svkalinin/.dm/db_template | ||||
|  | ||||
| ``` | ||||
|  | ||||
| После этого можно запустить программу, при первом запуске будет создана БД согласно шаблона: | ||||
|      | ||||
| ``` | ||||
| python3 gui.py | ||||
| ``` | ||||
|  | ||||
| # СУБД | ||||
|  | ||||
| Пока реализована работа с Mysql (или Mariadb) и sqlite (по умолчанию). Для из менения типа БД в конфиге меняем 'dbtype': | ||||
|  | ||||
| ``` | ||||
| dbtype = sqlite | ||||
|  | ||||
| или | ||||
|  | ||||
| dbtype = mysql | ||||
| ``` | ||||
|  | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								__pycache__/dm.cpython-36.pyc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								__pycache__/dm.cpython-36.pyc
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -6,8 +6,8 @@ | ||||
|       "fieldList": [ | ||||
|         { | ||||
|           "fName": "id", | ||||
|           "fDescription": "Номер п.п.", | ||||
|           "fType": "int(6)", | ||||
|           "fDescription": "UID", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "PRIMARY KEY", | ||||
|           "autoIncrement": "yes", | ||||
|           "relation": [] | ||||
| @@ -60,8 +60,8 @@ | ||||
|       "fieldList": [ | ||||
|         { | ||||
|           "fName": "id", | ||||
|           "fDescription": "Номер п.п.", | ||||
|           "fType": "int(6)", | ||||
|           "fDescription": "UID", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "PRIMARY KEY", | ||||
|           "autoIncrement": "yes", | ||||
|           "relation": [] | ||||
| @@ -85,7 +85,7 @@ | ||||
|         { | ||||
|           "fName": "users_id", | ||||
|           "fDescription": "Владелец", | ||||
|           "fType": "int(6)", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["users.id", "last_name, name, middle_name"] | ||||
| @@ -93,7 +93,7 @@ | ||||
|         { | ||||
|           "fName": "parent_id", | ||||
|           "fDescription": "Родительский документ", | ||||
|           "fType": "int(6)", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["docs.id", "doc_name"] | ||||
| @@ -106,8 +106,8 @@ | ||||
|       "fieldList": [ | ||||
|         { | ||||
|           "fName": "id", | ||||
|           "fDescription": "Номер п.п.", | ||||
|           "fType": "int(6)", | ||||
|           "fDescription": "UID", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "PRIMARY KEY", | ||||
|           "autoIncrement": "yes", | ||||
|           "relation": [] | ||||
| @@ -122,7 +122,7 @@ | ||||
|         }, | ||||
|         { | ||||
|           "fName": "city", | ||||
|           "fDescription": "Населеннй пункт", | ||||
|           "fDescription": "Населенный пункт", | ||||
|           "fType": "varchar(200)", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
| @@ -147,54 +147,116 @@ | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "tableName": "test", | ||||
|       "tableDescription": "Шляпа", | ||||
|       "tableName": "items", | ||||
|       "tableDescription": "Оборудование", | ||||
|       "fieldList": [ | ||||
|         { | ||||
|           "fName": "id", | ||||
|           "fDescription": "Номер п.п.", | ||||
|           "fType": "int(11)", | ||||
|           "fDescription": "UID", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "PRIMARY KEY", | ||||
|           "autoIncrement": "yes", | ||||
|           "relation": [] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "user", | ||||
|           "fDescription": "Юзер шляпы", | ||||
|           "fType": "int(11)", | ||||
|           "fName": "item_name", | ||||
|           "fDescription": "Наименование", | ||||
|           "fType": "VARCHAR(100)", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["users.id", "last_name, name, middle_name"] | ||||
|           "relation": [] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "item_address", | ||||
|           "fDescription": "Место расположения", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["address.id", "city, street, house"] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "item_type", | ||||
|           "fDescription": "Тип", | ||||
|           "fType": "CHAR(20)", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["itemtype.id", "type_name"] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "inventory_number", | ||||
|           "fDescription": "Инвентарный номер", | ||||
|           "fType": "CHAR(10)", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": [] | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "tableName": "test2", | ||||
|       "tableDescription": "Шляпа2", | ||||
|       "tableName": "itemtype", | ||||
|       "tableDescription": "Тип оборудования", | ||||
|       "fieldList": [ | ||||
|         { | ||||
|           "fName": "id", | ||||
|           "fDescription": "Номер п.п.", | ||||
|           "fType": "int(11)", | ||||
|           "fDescription": "UID", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "PRIMARY KEY", | ||||
|           "autoIncrement": "yes", | ||||
|           "relation": [] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "ins_date", | ||||
|           "fDescription": "Дата добавления", | ||||
|           "fName": "type_name", | ||||
|           "fDescription": "Тип", | ||||
|           "fType": "VARCHAR(100)", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": [] | ||||
|         } | ||||
|       ] | ||||
|     }, | ||||
|     { | ||||
|       "tableName": "itemrelocation", | ||||
|       "tableDescription": "Перемещения", | ||||
|       "fieldList": [ | ||||
|         { | ||||
|           "fName": "id", | ||||
|           "fDescription": "UID", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "PRIMARY KEY", | ||||
|           "autoIncrement": "yes", | ||||
|           "relation": [] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "item_id", | ||||
|           "fDescription": "Оборудование", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["items.id", "item_name, inventory_number"] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "source_place", | ||||
|           "fDescription": "Откуда", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["address.id", "city, street, house"] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "destination_place", | ||||
|           "fDescription": "Куда", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["address.id", "city, street, house"] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "create_datetime", | ||||
|           "fDescription": "Дата перемещения", | ||||
|           "fType": "DATETIME", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": [] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "user", | ||||
|           "fDescription": "Юзер шляпы", | ||||
|           "fType": "int(11)", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["users.id", "last_name, name, middle_name"] | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
							
								
								
									
										141
									
								
								db_template/library.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								db_template/library.json
									
									
									
									
									
										Normal file
									
								
							| @@ -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": [] | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										72
									
								
								db_template/radio-catalog.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								db_template/radio-catalog.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| { | ||||
|   "tables": [ | ||||
|     { | ||||
|       "tableName": "type", | ||||
|       "tableDescription": "Тип элемента", | ||||
|       "fieldList": [ | ||||
|         { | ||||
|           "fName": "id", | ||||
|           "fDescription": "Номер п.п.", | ||||
|           "fType": "INT(6)", | ||||
|           "index": "PRIMARY KEY", | ||||
|           "autoIncrement": "yes", | ||||
|           "relation": [] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "name", | ||||
|           "fDescription": "Тип элемента", | ||||
|           "fType": "char(20)", | ||||
|           "index": "yes", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": [] | ||||
|         } | ||||
|       ] | ||||
|      }, | ||||
|      { | ||||
|       "tableName": "items", | ||||
|       "tableDescription": "Элементы", | ||||
|       "fieldList": [ | ||||
|         { | ||||
|           "fName": "id", | ||||
|           "fDescription": "Номер п.п.", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "PRIMARY KEY", | ||||
|           "autoIncrement": "yes", | ||||
|           "relation": [] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "item_name", | ||||
|           "fDescription": "Наименование", | ||||
|           "fType": "varchar(100)", | ||||
|           "index": "yes", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": [] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "description", | ||||
|           "fDescription": "Описание", | ||||
|           "fType": "varchar(200)", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": [] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "type_id", | ||||
|           "fDescription": "Тип", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": ["type.id", "name"] | ||||
|         }, | ||||
|         { | ||||
|           "fName": "count", | ||||
|           "fDescription": "Количество", | ||||
|           "fType": "INTEGER", | ||||
|           "index": "no", | ||||
|           "autoIncrement": "no", | ||||
|           "relation": [] | ||||
|         } | ||||
|       ] | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										127
									
								
								dm.py
									
									
									
									
									
								
							
							
						
						
									
										127
									
								
								dm.py
									
									
									
									
									
								
							| @@ -3,8 +3,8 @@ import json, os, configparser, shutil, re | ||||
| from datetime import datetime, date, time | ||||
|  | ||||
| def firstInit(): | ||||
|     # Инициализация переменныхб создание конфигруационного файла, копирование шаблонов | ||||
|     global db_type, db_hostname, db_user, db_password, db_name, template_file, db_type | ||||
|     # Инициализация переменных создание конфигруационного файла, копирование шаблонов | ||||
|     global db_type, db_hostname, db_user, db_password, db_name, template_file, db_type, template_dir | ||||
|     config = configparser.RawConfigParser() | ||||
|     # проверяем тип ОС | ||||
|     if os.name == "nt": | ||||
| @@ -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') | ||||
| @@ -39,6 +39,7 @@ def firstInit(): | ||||
|         config.read(cfg_file) | ||||
|  | ||||
|     work_dir = config.get('Directory', 'work_dir') | ||||
|     global template_dir | ||||
|     template_dir = config.get('Directory', 'template_dir') | ||||
|     db_type = config.get('DataBase', 'db_type') | ||||
|     db_hostname =  config.get('DataBase', 'db_hostname') | ||||
| @@ -59,11 +60,13 @@ def firstInit(): | ||||
|     else: | ||||
|         os.mkdir(template_dir) | ||||
|     # копируем и читаем файл шаблон БД | ||||
|     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 already exists") | ||||
|         print("Template file already exists " + template_file) | ||||
|     else: | ||||
|         shutil.copy('tables.json', template_file) | ||||
|         shutil.copy('db_template/dm.json', template_file) | ||||
|  | ||||
|  | ||||
| def dbConnect(): | ||||
| @@ -167,17 +170,18 @@ def createTables(tbl_list): | ||||
|         i = i + 1 | ||||
|         dbTablesDescriptionList.append(one_Table_descr) | ||||
|         dbTablesStructList.append(one_Table_struct) | ||||
|         #print(qwery_create) | ||||
|         print(qwery_create) | ||||
|         c.execute(qwery_create) | ||||
|     return dbTablesNamesList | ||||
|  | ||||
| def initDBstructure(): | ||||
|     global dbTablesDescriptionList, template_file, tblNamesList | ||||
|     table_list = open(template_file, "r", encoding="utf-8") | ||||
|     data = json.load(table_list, encoding="utf-8") | ||||
|     tbl_list = data["tables"] | ||||
|     tblNamesList = createTables(tbl_list) | ||||
|  | ||||
|     # data = json.load(table_list, encoding="utf-8") | ||||
|     data = json.load(table_list) | ||||
|     #tbl_list = data["tables"] | ||||
|     #tblNamesList = createTables(tbl_list) | ||||
|     tblNamesList = createTables(data["tables"]) | ||||
|     return tblNamesList | ||||
|  | ||||
| # выборка данных из заданной таблицы | ||||
| @@ -186,6 +190,7 @@ def selectData(tbl): | ||||
|     # если юольше 1 поля добавить CONCAT | ||||
|     qwery = "SELECT " | ||||
|     subqwery = "" | ||||
|     #print(dbTablesStructList) | ||||
|     for item in dbTablesStructList: | ||||
|         if item[0] == tbl: | ||||
|             for field in item[1]: | ||||
| @@ -204,20 +209,17 @@ def selectData(tbl): | ||||
|                 else: | ||||
|                     subqwery = table1 | ||||
|                 # составляем подзапрос и подменяем им поле в запросе | ||||
|                 print(subqwery) | ||||
|  | ||||
|                 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(field,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) | ||||
| @@ -226,8 +228,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] | ||||
| @@ -235,8 +235,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]) | ||||
| @@ -265,26 +263,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) | ||||
| @@ -295,16 +287,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" | ||||
|  | ||||
| @@ -314,10 +300,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 = '' | ||||
| @@ -326,30 +308,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) | ||||
| @@ -385,20 +360,16 @@ 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) | ||||
|  | ||||
|  | ||||
|     print(qwery) | ||||
|     c.execute(qwery) | ||||
|     return c.fetchall() | ||||
| @@ -435,11 +406,11 @@ def getTablesDescriptionOfName(tblName): | ||||
| def deleteRecordsFromDB(tableName, valueList): | ||||
|     global c, db_type, conn | ||||
|     qwery = 'DELETE FROM {} WHERE '.format(tableName) | ||||
|     #print(qwery) | ||||
|     #print(valueList) | ||||
|     subQwery='' | ||||
|     i = 0 | ||||
|     for item in getFields(tableName): | ||||
|         print(item[0], item[1]) | ||||
|         #print(item[0], item[1]) | ||||
|         if item[1] == 'integer': | ||||
|             #subQwery = subQwery + item[0] + '=' + valueList[i] + ' AND ' | ||||
|             subQwery = '{}{}={} AND '.format(subQwery, item[0], valueList[i]) | ||||
| @@ -449,11 +420,61 @@ def deleteRecordsFromDB(tableName, valueList): | ||||
|         i += 1 | ||||
|     qwery += subQwery | ||||
|     qwery = qwery.rstrip('AND ').replace("='None'", " IS NULL") | ||||
|     qwery = qwery.rstrip('AND ').replace("=None", " IS NULL") | ||||
|     qwery = qwery.rstrip('AND ').replace("=NULL", " IS NULL") | ||||
|     print(qwery) | ||||
|     c.execute(qwery) | ||||
|     conn.commit() | ||||
|     return | ||||
|  | ||||
| # Редактирование записи в БД | ||||
| def editDataIntoBD(dataList): | ||||
|     global c, conn | ||||
|     dbConnect() | ||||
|     tableName = dataList[0] | ||||
|     qwery = 'UPDATE {} SET '.format(tableName) | ||||
|     #qweryData = '' | ||||
|     qweryField = '' | ||||
|     qweryWhere = '' | ||||
|     for item in dataList[1]: | ||||
|         fType = getFieldType(tableName, item[0]) | ||||
|         # проверяем если значение поля пустое то в запрос оно не включается | ||||
|         if item[1] != '': | ||||
|             qweryField = '{}{}='.format(qweryField,item[0]) | ||||
|  | ||||
|             if fType == 'integer': | ||||
|                 qweryField = '{}{},'.format(qweryField,item[1]) | ||||
|             elif fType == 'datetime': | ||||
|                 # преобразуем дату всяко разно | ||||
|                 dt = datetime.strptime(item[1], "%d.%m.%y %H:%M") | ||||
|                 item[1] = str(dt) | ||||
|                 qweryField = "{}'{}',".format(qweryField,item[1]) | ||||
|             elif fType == 'date': | ||||
|                 d = item[1].split('.') | ||||
|                 myDate = '{}-{}-{}'.format(d[2], d[1], d[1]) | ||||
|                 item[1] = str(myDate) | ||||
|                 qweryField = "{}'{}',".format(qweryField, item[1]) | ||||
|             else: | ||||
|                 qweryField = "{}'{}',".format(qweryField, item[1]) | ||||
|     qwery = '{}{} WHERE {};'.format(qwery, qweryField.rstrip(','), qweryWhere) | ||||
|  | ||||
|     print(qwery) | ||||
|     #c.execute(qwery) | ||||
|     #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() | ||||
| dbConnect() | ||||
|   | ||||
							
								
								
									
										148
									
								
								gui.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							
							
						
						
									
										148
									
								
								gui.py
									
									
									
									
									
										
										
										Normal file → Executable file
									
								
							| @@ -5,6 +5,8 @@ import sys | ||||
| from PyQt5.QtCore import * | ||||
| from PyQt5.QtGui import * | ||||
| from PyQt5.QtWidgets import * | ||||
| #from PyQt5.QtWidgets import (QMainWindow, QTextEdit, QAction, QFileDialog, QApplication) | ||||
| #from PyQt5.QtGui import QIcon | ||||
|  | ||||
| #import pymysql | ||||
| import dm | ||||
| @@ -33,6 +35,7 @@ class MyTable(QTableWidget): | ||||
|     def contextMenuEvent(self, event): | ||||
|         Rmenu = QMenu(self) | ||||
|         addRecord = Rmenu.addAction("Добавить запись") | ||||
|         editRecord = Rmenu.addAction("Редактировать запись") | ||||
|         delRecord = Rmenu.addAction("Удалить запись") | ||||
|         showRelations = Rmenu.addAction("Показать связанные документы") | ||||
|         action = Rmenu.exec_(self.mapToGlobal(event.pos())) | ||||
| @@ -46,6 +49,13 @@ class MyTable(QTableWidget): | ||||
|         elif action == addRecord: | ||||
|             print("Добавить запись  ") | ||||
|             addNewRecord() | ||||
|         elif action == editRecord: | ||||
|             row = self.rowAt(event.pos().y()) | ||||
|             col = self.columnAt(event.pos().x()) | ||||
|             #print("Удаляем row:%d, col:%d" % (row, col)) | ||||
|             item = self.item(self.currentIndex().row(), self.currentIndex().column()) | ||||
|             print("Редактировать запись  ") | ||||
|             self.editCurrentRecord(row) | ||||
|         elif action == showRelations: | ||||
|             item = self.item(self.currentIndex().row(), self.currentIndex().column()) | ||||
|             showRelationsRecords(self.currentIndex().column(), item.text()) | ||||
| @@ -69,6 +79,24 @@ class MyTable(QTableWidget): | ||||
|             #print(self.item(row, i).text()) | ||||
|             i += 1 | ||||
|         deleteRecord(self, row, self.dbTableName, valueList) | ||||
|     # редактирование записи | ||||
|     def editCurrentRecord(self, row): | ||||
|         valueList = [] | ||||
|         #print(self.dbTableName, row, self.statusTip()) | ||||
|         i = 0 | ||||
|         #print(self.columnCount()) | ||||
|         #print(self.verticalHeaderItem(row).text(), '---') | ||||
|         while i < self.columnCount(): | ||||
|             if self.item(row, i): | ||||
|                 val = self.item(row, i).text() | ||||
|                 print(val) | ||||
|                 valueList.append(str(val)) | ||||
|             else: | ||||
|                 valueList.append('') | ||||
|  | ||||
|             i += 1 | ||||
|         print(valueList) | ||||
|         editRecord(self, row, self.dbTableName, valueList) | ||||
|  | ||||
| # Диалог выбора связанных данных | ||||
| class RelationDataView(QMainWindow): | ||||
| @@ -170,9 +198,13 @@ class EditForm(QMainWindow): | ||||
|     lblList = [] | ||||
|     editList = [] | ||||
|  | ||||
|     def __init__(self, tblName, tblDescr): | ||||
|     def __init__(self, tblName, tblDescr, action): | ||||
|         super().__init__() | ||||
|         self.tblName = tblName | ||||
|         self.action = action | ||||
|         if action == 'edit': | ||||
|             self.setWindowTitle("Редактирование записи") | ||||
|         elif action == 'add': | ||||
|             self.setWindowTitle("Добавление записи") | ||||
|         #self.setGeometry(300, 300, 400, 400) | ||||
|         scroll_widget = QWidget() | ||||
| @@ -240,6 +272,7 @@ class EditForm(QMainWindow): | ||||
|                 edit.setValidator(integerValidator) | ||||
|             else: | ||||
|                 edit = QLineEdit() | ||||
|  | ||||
|             # создаём список полей и соответсвующих им QEdit | ||||
|             self.widgetsList.append([fName, edit]) | ||||
|  | ||||
| @@ -247,15 +280,15 @@ class EditForm(QMainWindow): | ||||
|             hboxEdit.addWidget(lbl2) | ||||
|             hboxEdit.addWidget(edit) | ||||
|             # добавляем к полю кнопку для вызова связанных | ||||
|             print(fName) | ||||
|             #print(fName) | ||||
|             listRelationTableAndField = dm.getRelationsForField(tblName, fName) | ||||
|  | ||||
|             print(listRelationTableAndField) | ||||
|             #print(listRelationTableAndField) | ||||
|             if listRelationTableAndField != 'q': | ||||
|                 tableRelation = listRelationTableAndField[0] | ||||
|                 fieldRelation = listRelationTableAndField[1] | ||||
|                 replaceField = listRelationTableAndField[2] | ||||
|                 print(tableRelation + '-' + fieldRelation +'-'+replaceField) | ||||
|                 #print(tableRelation + '-' + fieldRelation +'-'+replaceField) | ||||
|                 btnRelations = QPushButton('...') | ||||
|                 btnRelations.setFixedWidth(30) | ||||
|                 # добавляем название виджета в список соответсвия кнопок и таблиц БД | ||||
| @@ -284,7 +317,10 @@ class EditForm(QMainWindow): | ||||
|                 listFieldData.append([item[0], item[1].text()]) | ||||
|         listData.append(listFieldData) | ||||
|         #print(listData) | ||||
|         if self.action == 'add': | ||||
|             dm.insertDataIntoBD(listData) | ||||
|         elif self.action == 'edit': | ||||
|             dm.editDataIntoBD(listData) | ||||
|         self.close() | ||||
|     # выбираем данные для связанной таблицы | ||||
|     def openRelationTable(self): | ||||
| @@ -356,29 +392,38 @@ def addDataIntoTable(dbTableName, tblDataWidget, data='NULL'): | ||||
|     dbFieldRelationValueList = [] | ||||
|     for key in data: | ||||
|         n = 0 | ||||
|         #print(fieldNames, '\n', key) | ||||
|         print(key) | ||||
|         for item in key: | ||||
|             #print(m, n, item) | ||||
|             listRelationTableAndField = dm.getRelationsForField(dbTableName, fieldNames[n][0]) | ||||
|             #print('--->', fieldNames[n][1]) | ||||
|             if listRelationTableAndField != 'q': | ||||
|                 #print('yahooooo', fieldNames[n][0]) | ||||
|                 itemString = dm.re.search('>([0-9])+<(.+)', str(item)) | ||||
|                 # кривой алгоритм, надо придумывать что-то другое | ||||
|                 itemString = dm.re.search('>([0-9]+)<(.+)', str(item)) | ||||
|                 if itemString: | ||||
|                     #print('--->',itemString.groups()) | ||||
|                     newitem = QTableWidgetItem(itemString.groups()[1]) | ||||
|                     dbFieldRelationValueList.append([newitem, m, n, itemString.groups()[0], itemString.groups()[1]]) | ||||
|  | ||||
|                 else: | ||||
|                     newitem = QTableWidgetItem(str(item)) | ||||
|  | ||||
|                     dbFieldRelationValueList.append([newitem, m, n, 'None', 'None']) | ||||
|             else: | ||||
|                 # преобразуем все типы в строку | ||||
|                 newitem = QTableWidgetItem(str(item)) | ||||
|             #print(fieldNames[n][0]) | ||||
|             #print(str(item)) | ||||
|             # проверяем название поля и если это id то данные вносим в заголовок строки | ||||
|             # таким образом внесем уникальный ID в чётко определенное поле | ||||
|             #if fieldNames[n][0] == "id": | ||||
|             #   tblDataWidget.setVerticalHeaderItem(m, QTableWidgetItem(str(item))) | ||||
|             tblDataWidget.setItem(m, n, newitem) | ||||
|             n += 1 | ||||
|         m += 1 | ||||
|     #print(dbFieldRelationValueList) | ||||
| # Показ менб и панели инструментов | ||||
|  | ||||
| # Показ меню и панели инструментов | ||||
| def showMenuToolbar(window): | ||||
|     openFileAction = QAction(QIcon('img/open.gif'), 'Открыть', window) | ||||
|     openFileAction.setShortcut('Ctrl+O') | ||||
|     openFileAction.setStatusTip('Открыть') | ||||
|     openFileAction.triggered.connect(openTemplate) | ||||
|  | ||||
|     newAction = QAction(QIcon('img/new.gif'), 'Добавить', window) | ||||
|     newAction.setShortcut('Ins') | ||||
|     newAction.setStatusTip('Добавить') | ||||
| @@ -387,45 +432,46 @@ def showMenuToolbar(window): | ||||
|     deleteAction = QAction(QIcon('img/delete.gif'), 'Удалить', window) | ||||
|     deleteAction.setShortcut('Del') | ||||
|     deleteAction.setStatusTip('Удалить') | ||||
|     # deleteAction.triggered.connect(window.qqqq) | ||||
|  | ||||
|     exitAction = QAction(QIcon('img/exit.gif'), 'Выход', window) | ||||
|     exitAction.setShortcut('Ctrl+Q') | ||||
|     exitAction.setStatusTip('Выход') | ||||
|     exitAction.triggered.connect(window.close) | ||||
|     exitAction.setStatusTip('Выйти') | ||||
|     exitAction.triggered.connect(exit) | ||||
|  | ||||
|     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('Вырезать') | ||||
|     # cutAction.triggered.connect(window.close) | ||||
|  | ||||
|     copyAction = QAction(QIcon('img/copy.gif'), 'Копировать', window) | ||||
|     copyAction.setShortcut('Ctrl+С') | ||||
|     copyAction.setStatusTip('Копировать') | ||||
|     # copyAction.triggered.connect(window.close) | ||||
|  | ||||
|     pasteAction = QAction(QIcon('img/paste.gif'), 'Вставить', window) | ||||
|     pasteAction.setShortcut('Ctrl+V') | ||||
|     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) | ||||
|  | ||||
|     printAction = QAction(QIcon('img/print.gif'), 'Печатать', window) | ||||
|     printAction.setShortcut('Ctrl+P') | ||||
|     printAction.setStatusTip('Печатать') | ||||
|     # printAction.triggered.connect(window.close) | ||||
|  | ||||
|     window.statusBar() | ||||
|  | ||||
|     menubar = window.menuBar() | ||||
|     fileMenu = menubar.addMenu('&Файл') | ||||
|     fileMenu.addAction(openFileAction) | ||||
|     fileMenu.addAction(newAction) | ||||
|     fileMenu.addAction(deleteAction) | ||||
|     fileMenu.addAction(printAction) | ||||
|     fileMenu.addAction(structureAction) | ||||
|     fileMenu.addAction(exitAction) | ||||
|  | ||||
|     editMenu = menubar.addMenu('&Редактирование') | ||||
| @@ -439,6 +485,7 @@ def showMenuToolbar(window): | ||||
|     # toolbar = window.addToolBar('Редактирование') | ||||
|  | ||||
|     toolbar = window.addToolBar('Панель инструментов') | ||||
|     #toolbar.addAction(openFileAction) | ||||
|     toolbar.addAction(newAction) | ||||
|     toolbar.addAction(deleteAction) | ||||
|     toolbar.addAction(copyAction) | ||||
| @@ -457,7 +504,7 @@ def addNewRecord(): | ||||
|             tblName = i[0] | ||||
|  | ||||
|     #print(tblName) | ||||
|     editForm = EditForm(tblName, tblDescr) | ||||
|     editForm = EditForm(tblName, tblDescr, 'add') | ||||
|     editForm.show() | ||||
|     #editForm.setParent(listDBTables) | ||||
|     #editForm.show() | ||||
| @@ -497,27 +544,58 @@ def showRelationsRecords(fieldIndex, fieldValue): | ||||
|             addDataIntoTable(tbl, tblRelationsData, qweryResult) | ||||
|             # пишем название активной таблицы БД в строку статуса | ||||
|             tblRelationsData.setStatusTip(tbl) | ||||
|  | ||||
| # Удаление записи | ||||
| def deleteRecord(tableWidget, row, dbTableName, valueList): | ||||
|     global dbFieldRelationValueList | ||||
|     #print(tableWidget, row, dbTableName, valueList) | ||||
|     #print(self.columnCount()) | ||||
|     i = 0 | ||||
|     #print(valueList) | ||||
|     for val in valueList: | ||||
|         #print(tableWidget.item(row, i)) | ||||
|         #print('Значение из таблицы-->',valueList[i]) | ||||
|         for item in dbFieldRelationValueList: | ||||
|             if item[0] == tableWidget.item(row, i): | ||||
|                 #print(item[0]) | ||||
|                 #print('еще значение',tableWidget.item(row, i).text(), item[0]) | ||||
|                 value = item[3] | ||||
|                 valueList.pop(i) | ||||
|                 valueList.insert(i, item[3]) | ||||
|  | ||||
|         i += 1 | ||||
|     #print(valueList) | ||||
|     dm.deleteRecordsFromDB(dbTableName, valueList) | ||||
| # Редактирование записи | ||||
| def editRecord(tableWidget, row, dbTableName, valueList): | ||||
|     global dbFieldRelationValueList | ||||
|     editForm = EditForm(dbTableName, dm.getTablesDescriptionOfName(dbTableName), 'edit') | ||||
|     editForm.show() | ||||
|     i = 0 | ||||
|     for val in valueList: | ||||
|         for item in dbFieldRelationValueList: | ||||
|             if item[0] == tableWidget.item(row, i): | ||||
|                 value = item[3] | ||||
|                 valueList.pop(i) | ||||
|                 valueList.insert(i, item[3]) | ||||
|                 val = item[3] | ||||
|                 #print(val) | ||||
|         editForm.widgetsList[i][1].setText(val) | ||||
|         i += 1 | ||||
|     #print(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 openTemplate(): | ||||
|     global template_file, template_dir | ||||
|     template_file = QFileDialog.getOpenFileName(None, 'Open file', template_dir)[0] | ||||
|     dm.initDBstructure(template_file) | ||||
|  | ||||
|  | ||||
| def main(): | ||||
|     global dbTablesList, listDBTables, tabRelationsData, dbFieldRelationValueList | ||||
| @@ -555,12 +633,12 @@ def main(): | ||||
|     print(dm.getTablesNameOfDescription(listDBTables.model().data(listDBTables.currentIndex()))) | ||||
|  | ||||
|  | ||||
|     mainWin.setGeometry(300, 300, 800, 600) | ||||
|     mainWin.setGeometry(300, 300, 1024, 800) | ||||
|     mainWin.setWindowTitle('Data manipulator') | ||||
|     mainWin.show() | ||||
|  | ||||
|     return app.exec_() | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|     main() | ||||
|     print(template_dir) | ||||
|   | ||||
							
								
								
									
										2
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| pymysql==1.0.2 | ||||
| PyQt5==5.15.7 | ||||
							
								
								
									
										93
									
								
								test.py
									
									
									
									
									
								
							
							
						
						
									
										93
									
								
								test.py
									
									
									
									
									
								
							| @@ -1,93 +0,0 @@ | ||||
| #!/usr/bin/env python | ||||
|  | ||||
|  | ||||
| ############################################################################# | ||||
| ## | ||||
| ## Copyright (C) 2013 Riverbank Computing Limited. | ||||
| ## Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | ||||
| ## All rights reserved. | ||||
| ## | ||||
| ## This file is part of the examples of PyQt. | ||||
| ## | ||||
| ## $QT_BEGIN_LICENSE:BSD$ | ||||
| ## You may use this file under the terms of the BSD license as follows: | ||||
| ## | ||||
| ## "Redistribution and use in source and binary forms, with or without | ||||
| ## modification, are permitted provided that the following conditions are | ||||
| ## met: | ||||
| ##   * Redistributions of source code must retain the above copyright | ||||
| ##     notice, this list of conditions and the following disclaimer. | ||||
| ##   * Redistributions in binary form must reproduce the above copyright | ||||
| ##     notice, this list of conditions and the following disclaimer in | ||||
| ##     the documentation and/or other materials provided with the | ||||
| ##     distribution. | ||||
| ##   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor | ||||
| ##     the names of its contributors may be used to endorse or promote | ||||
| ##     products derived from this software without specific prior written | ||||
| ##     permission. | ||||
| ## | ||||
| ## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||||
| ## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||||
| ## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||||
| ## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||||
| ## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||||
| ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||
| ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||||
| ## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||||
| ## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||||
| ## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||||
| ## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." | ||||
| ## $QT_END_LICENSE$ | ||||
| ## | ||||
| ############################################################################# | ||||
|  | ||||
|  | ||||
| from PyQt5.QtCore import QModelIndex, Qt | ||||
| from PyQt5.QtGui import QStandardItemModel | ||||
| from PyQt5.QtWidgets import QApplication, QItemDelegate, QSpinBox, QTableView | ||||
|  | ||||
|  | ||||
| class SpinBoxDelegate(QItemDelegate): | ||||
|     def createEditor(self, parent, option, index): | ||||
|         editor = QSpinBox(parent) | ||||
|         editor.setMinimum(0) | ||||
|         editor.setMaximum(100) | ||||
|  | ||||
|         return editor | ||||
|  | ||||
|     def setEditorData(self, spinBox, index): | ||||
|         value = index.model().data(index, Qt.EditRole) | ||||
|  | ||||
|         spinBox.setValue(value) | ||||
|  | ||||
|     def setModelData(self, spinBox, model, index): | ||||
|         spinBox.interpretText() | ||||
|         value = spinBox.value() | ||||
|  | ||||
|         model.setData(index, value, Qt.EditRole) | ||||
|  | ||||
|     def updateEditorGeometry(self, editor, option, index): | ||||
|         editor.setGeometry(option.rect) | ||||
|  | ||||
|  | ||||
| if __name__ == '__main__': | ||||
|  | ||||
|     import sys | ||||
|  | ||||
|     app = QApplication(sys.argv) | ||||
|  | ||||
|     model = QStandardItemModel(4, 4) | ||||
|     tableView = QTableView() | ||||
|     tableView.setModel(model) | ||||
|  | ||||
|     delegate = SpinBoxDelegate() | ||||
|     tableView.setItemDelegate(delegate) | ||||
|  | ||||
|     for row in range(4): | ||||
|         for column in range(4): | ||||
|             index = model.index(row, column, QModelIndex()) | ||||
|             model.setData(index, (row + 1) * (column + 1)) | ||||
|  | ||||
|     tableView.setWindowTitle("Spin Box Delegate") | ||||
|     tableView.show() | ||||
|     sys.exit(app.exec_()) | ||||
		Reference in New Issue
	
	Block a user