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": [
|
"fieldList": [
|
||||||
{
|
{
|
||||||
"fName": "id",
|
"fName": "id",
|
||||||
"fDescription": "Номер п.п.",
|
"fDescription": "UID",
|
||||||
"fType": "int(6)",
|
"fType": "INTEGER",
|
||||||
"index": "PRIMARY KEY",
|
"index": "PRIMARY KEY",
|
||||||
"autoIncrement": "yes",
|
"autoIncrement": "yes",
|
||||||
"relation": []
|
"relation": []
|
||||||
@ -60,8 +60,8 @@
|
|||||||
"fieldList": [
|
"fieldList": [
|
||||||
{
|
{
|
||||||
"fName": "id",
|
"fName": "id",
|
||||||
"fDescription": "Номер п.п.",
|
"fDescription": "UID",
|
||||||
"fType": "int(6)",
|
"fType": "INTEGER",
|
||||||
"index": "PRIMARY KEY",
|
"index": "PRIMARY KEY",
|
||||||
"autoIncrement": "yes",
|
"autoIncrement": "yes",
|
||||||
"relation": []
|
"relation": []
|
||||||
@ -85,7 +85,7 @@
|
|||||||
{
|
{
|
||||||
"fName": "users_id",
|
"fName": "users_id",
|
||||||
"fDescription": "Владелец",
|
"fDescription": "Владелец",
|
||||||
"fType": "int(6)",
|
"fType": "INTEGER",
|
||||||
"index": "no",
|
"index": "no",
|
||||||
"autoIncrement": "no",
|
"autoIncrement": "no",
|
||||||
"relation": ["users.id", "last_name, name, middle_name"]
|
"relation": ["users.id", "last_name, name, middle_name"]
|
||||||
@ -93,7 +93,7 @@
|
|||||||
{
|
{
|
||||||
"fName": "parent_id",
|
"fName": "parent_id",
|
||||||
"fDescription": "Родительский документ",
|
"fDescription": "Родительский документ",
|
||||||
"fType": "int(6)",
|
"fType": "INTEGER",
|
||||||
"index": "no",
|
"index": "no",
|
||||||
"autoIncrement": "no",
|
"autoIncrement": "no",
|
||||||
"relation": ["docs.id", "doc_name"]
|
"relation": ["docs.id", "doc_name"]
|
||||||
@ -106,8 +106,8 @@
|
|||||||
"fieldList": [
|
"fieldList": [
|
||||||
{
|
{
|
||||||
"fName": "id",
|
"fName": "id",
|
||||||
"fDescription": "Номер п.п.",
|
"fDescription": "UID",
|
||||||
"fType": "int(6)",
|
"fType": "INTEGER",
|
||||||
"index": "PRIMARY KEY",
|
"index": "PRIMARY KEY",
|
||||||
"autoIncrement": "yes",
|
"autoIncrement": "yes",
|
||||||
"relation": []
|
"relation": []
|
||||||
@ -122,7 +122,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fName": "city",
|
"fName": "city",
|
||||||
"fDescription": "Населеннй пункт",
|
"fDescription": "Населенный пункт",
|
||||||
"fType": "varchar(200)",
|
"fType": "varchar(200)",
|
||||||
"index": "no",
|
"index": "no",
|
||||||
"autoIncrement": "no",
|
"autoIncrement": "no",
|
||||||
@ -147,54 +147,116 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tableName": "test",
|
"tableName": "items",
|
||||||
"tableDescription": "Шляпа",
|
"tableDescription": "Оборудование",
|
||||||
"fieldList": [
|
"fieldList": [
|
||||||
{
|
{
|
||||||
"fName": "id",
|
"fName": "id",
|
||||||
"fDescription": "Номер п.п.",
|
"fDescription": "UID",
|
||||||
"fType": "int(11)",
|
"fType": "INTEGER",
|
||||||
"index": "PRIMARY KEY",
|
"index": "PRIMARY KEY",
|
||||||
"autoIncrement": "yes",
|
"autoIncrement": "yes",
|
||||||
"relation": []
|
"relation": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fName": "user",
|
"fName": "item_name",
|
||||||
"fDescription": "Юзер шляпы",
|
"fDescription": "Наименование",
|
||||||
"fType": "int(11)",
|
"fType": "VARCHAR(100)",
|
||||||
"index": "no",
|
"index": "no",
|
||||||
"autoIncrement": "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",
|
"tableName": "itemtype",
|
||||||
"tableDescription": "Шляпа2",
|
"tableDescription": "Тип оборудования",
|
||||||
"fieldList": [
|
"fieldList": [
|
||||||
{
|
{
|
||||||
"fName": "id",
|
"fName": "id",
|
||||||
"fDescription": "Номер п.п.",
|
"fDescription": "UID",
|
||||||
"fType": "int(11)",
|
"fType": "INTEGER",
|
||||||
"index": "PRIMARY KEY",
|
"index": "PRIMARY KEY",
|
||||||
"autoIncrement": "yes",
|
"autoIncrement": "yes",
|
||||||
"relation": []
|
"relation": []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"fName": "ins_date",
|
"fName": "type_name",
|
||||||
"fDescription": "Дата добавления",
|
"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",
|
"fType": "DATETIME",
|
||||||
"index": "no",
|
"index": "no",
|
||||||
"autoIncrement": "no",
|
"autoIncrement": "no",
|
||||||
"relation": []
|
"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
|
from datetime import datetime, date, time
|
||||||
|
|
||||||
def firstInit():
|
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()
|
config = configparser.RawConfigParser()
|
||||||
# проверяем тип ОС
|
# проверяем тип ОС
|
||||||
if os.name == "nt":
|
if os.name == "nt":
|
||||||
@ -19,7 +19,7 @@ def firstInit():
|
|||||||
cfg_file = os.path.join(cfg_dir, 'dm.cfg')
|
cfg_file = os.path.join(cfg_dir, 'dm.cfg')
|
||||||
# создадим файл конфигурации
|
# создадим файл конфигурации
|
||||||
config.add_section('DataBase')
|
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_hostname', 'localhost')
|
||||||
config.set('DataBase', 'db_name', 'dm')
|
config.set('DataBase', 'db_name', 'dm')
|
||||||
config.set('DataBase', 'db_user', 'dm')
|
config.set('DataBase', 'db_user', 'dm')
|
||||||
@ -39,6 +39,7 @@ def firstInit():
|
|||||||
config.read(cfg_file)
|
config.read(cfg_file)
|
||||||
|
|
||||||
work_dir = config.get('Directory', 'work_dir')
|
work_dir = config.get('Directory', 'work_dir')
|
||||||
|
global template_dir
|
||||||
template_dir = config.get('Directory', 'template_dir')
|
template_dir = config.get('Directory', 'template_dir')
|
||||||
db_type = config.get('DataBase', 'db_type')
|
db_type = config.get('DataBase', 'db_type')
|
||||||
db_hostname = config.get('DataBase', 'db_hostname')
|
db_hostname = config.get('DataBase', 'db_hostname')
|
||||||
@ -59,11 +60,13 @@ def firstInit():
|
|||||||
else:
|
else:
|
||||||
os.mkdir(template_dir)
|
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):
|
if os.path.isfile(template_file):
|
||||||
print("Template file already exists")
|
print("Template file already exists " + template_file)
|
||||||
else:
|
else:
|
||||||
shutil.copy('tables.json', template_file)
|
shutil.copy('db_template/dm.json', template_file)
|
||||||
|
|
||||||
|
|
||||||
def dbConnect():
|
def dbConnect():
|
||||||
@ -167,17 +170,18 @@ def createTables(tbl_list):
|
|||||||
i = i + 1
|
i = i + 1
|
||||||
dbTablesDescriptionList.append(one_Table_descr)
|
dbTablesDescriptionList.append(one_Table_descr)
|
||||||
dbTablesStructList.append(one_Table_struct)
|
dbTablesStructList.append(one_Table_struct)
|
||||||
#print(qwery_create)
|
print(qwery_create)
|
||||||
c.execute(qwery_create)
|
c.execute(qwery_create)
|
||||||
return dbTablesNamesList
|
return dbTablesNamesList
|
||||||
|
|
||||||
def initDBstructure():
|
def initDBstructure():
|
||||||
global dbTablesDescriptionList, template_file, tblNamesList
|
global dbTablesDescriptionList, template_file, tblNamesList
|
||||||
table_list = open(template_file, "r", encoding="utf-8")
|
table_list = open(template_file, "r", encoding="utf-8")
|
||||||
data = json.load(table_list, encoding="utf-8")
|
# data = json.load(table_list, encoding="utf-8")
|
||||||
tbl_list = data["tables"]
|
data = json.load(table_list)
|
||||||
tblNamesList = createTables(tbl_list)
|
#tbl_list = data["tables"]
|
||||||
|
#tblNamesList = createTables(tbl_list)
|
||||||
|
tblNamesList = createTables(data["tables"])
|
||||||
return tblNamesList
|
return tblNamesList
|
||||||
|
|
||||||
# выборка данных из заданной таблицы
|
# выборка данных из заданной таблицы
|
||||||
@ -186,6 +190,7 @@ def selectData(tbl):
|
|||||||
# если юольше 1 поля добавить CONCAT
|
# если юольше 1 поля добавить CONCAT
|
||||||
qwery = "SELECT "
|
qwery = "SELECT "
|
||||||
subqwery = ""
|
subqwery = ""
|
||||||
|
#print(dbTablesStructList)
|
||||||
for item in dbTablesStructList:
|
for item in dbTablesStructList:
|
||||||
if item[0] == tbl:
|
if item[0] == tbl:
|
||||||
for field in item[1]:
|
for field in item[1]:
|
||||||
@ -204,20 +209,17 @@ def selectData(tbl):
|
|||||||
else:
|
else:
|
||||||
subqwery = table1
|
subqwery = table1
|
||||||
# составляем подзапрос и подменяем им поле в запросе
|
# составляем подзапрос и подменяем им поле в запросе
|
||||||
|
print(subqwery)
|
||||||
|
|
||||||
if db_type == "mysql":
|
if db_type == "mysql":
|
||||||
field_replace = field_replace.replace(",", ",' ',")
|
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 {}"\
|
||||||
# subqwery = "(SELECT CONCAT({}) FROM {} WHERE {}.{}={}.{}) AS {}"\
|
.format(tbl,field,field_replace,subqwery,table1,field1,tbl,field,field)
|
||||||
# .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)
|
|
||||||
elif db_type == "sqlite":
|
elif db_type == "sqlite":
|
||||||
field_replace = field_replace.replace(",", " || ' ' ||")
|
field_replace = field_replace.replace(",", " || ' ' ||")
|
||||||
#subqwery = "(SELECT (" + field_replace + ") FROM " + subqwery +" WHERE "+ table1 + "." + field1 +"="+ tbl +"."+ field +") AS " + field
|
|
||||||
subqwery = "(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}" \
|
subqwery = "(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}" \
|
||||||
.format(field_replace, subqwery, table1, field1, tbl, field, field)
|
.format(field_replace, subqwery, table1, field1, tbl, field, field)
|
||||||
qwery = qwery.replace(field, subqwery)
|
qwery = qwery.replace(field, subqwery)
|
||||||
#qwery = qwery.rstrip(',') + " FROM " + tbl + " LIMIT 10000"
|
|
||||||
qwery = '{} FROM {} LIMIT 10000'.format(qwery.rstrip(','), tbl)
|
qwery = '{} FROM {} LIMIT 10000'.format(qwery.rstrip(','), tbl)
|
||||||
print(qwery)
|
print(qwery)
|
||||||
c.execute(qwery)
|
c.execute(qwery)
|
||||||
@ -226,8 +228,6 @@ def selectData(tbl):
|
|||||||
# получаем на вход имя таблицы и возвращаем список заголовков полей
|
# получаем на вход имя таблицы и возвращаем список заголовков полей
|
||||||
def getTableStructure(tbl):
|
def getTableStructure(tbl):
|
||||||
global dbTablesDescriptionList, dbTablesStructList
|
global dbTablesDescriptionList, dbTablesStructList
|
||||||
#print(dbTablesDescriptionList)
|
|
||||||
#print(dbTablesStructList)
|
|
||||||
for item in dbTablesDescriptionList:
|
for item in dbTablesDescriptionList:
|
||||||
if item[0] == tbl:
|
if item[0] == tbl:
|
||||||
return item[1]
|
return item[1]
|
||||||
@ -235,8 +235,6 @@ def getTableStructure(tbl):
|
|||||||
# Получаем список названий полей и типов для заданной таблицы
|
# Получаем список названий полей и типов для заданной таблицы
|
||||||
def getFields(tbl):
|
def getFields(tbl):
|
||||||
global dbTablesDescriptionList, dbTablesStructList
|
global dbTablesDescriptionList, dbTablesStructList
|
||||||
#print(dbTablesDescriptionList)
|
|
||||||
#print(dbTablesStructList)
|
|
||||||
for item in dbTablesStructList:
|
for item in dbTablesStructList:
|
||||||
if item[0] == tbl:
|
if item[0] == tbl:
|
||||||
#print(item[1])
|
#print(item[1])
|
||||||
@ -265,26 +263,20 @@ def fieldTypeConvert(ftype):
|
|||||||
fType = 'character'
|
fType = 'character'
|
||||||
else:
|
else:
|
||||||
fType = ftype
|
fType = ftype
|
||||||
|
#print(fType)
|
||||||
return fType
|
return fType
|
||||||
|
|
||||||
def getFieldType(tbl, field):
|
def getFieldType(tbl, field):
|
||||||
global dbTablesDescriptionList, dbTablesStructList
|
global dbTablesDescriptionList, dbTablesStructList
|
||||||
#print(dbTablesDescriptionList)
|
|
||||||
#print(dbTablesStructList)
|
|
||||||
for item in dbTablesStructList:
|
for item in dbTablesStructList:
|
||||||
if item[0] == tbl:
|
if item[0] == tbl:
|
||||||
for i in item[1]:
|
for i in item[1]:
|
||||||
if i[0] == field:
|
if i[0] == field:
|
||||||
fType = i[1]
|
fType = i[1]
|
||||||
return fType
|
return fType
|
||||||
#print(item[1])
|
|
||||||
#return item[1]
|
|
||||||
|
|
||||||
def getRelationsForField(tblSearch, fieldName):
|
def getRelationsForField(tblSearch, fieldName):
|
||||||
global dbTablesStructList, c, db_type
|
global dbTablesStructList, c, db_type
|
||||||
#print("Ищем связи для:" +tblSearch +','+ fieldName)
|
|
||||||
#print(dbTablesStructList)
|
|
||||||
#searchField = tblSearch + '.' + fieldName
|
|
||||||
dataList = []
|
dataList = []
|
||||||
for item in dbTablesStructList:
|
for item in dbTablesStructList:
|
||||||
#print(item)
|
#print(item)
|
||||||
@ -295,16 +287,10 @@ def getRelationsForField(tblSearch, fieldName):
|
|||||||
if tblName == tblSearch:
|
if tblName == tblSearch:
|
||||||
# выдергиваем из списка название и поле нужной нам таблицы
|
# выдергиваем из списка название и поле нужной нам таблицы
|
||||||
if rel[0] == fieldName:
|
if rel[0] == fieldName:
|
||||||
#print('table - ' + tblName)
|
|
||||||
##print('field - ' + fieldName)
|
|
||||||
#print('relation - ' + str(rel))
|
|
||||||
l = rel[1][0].split('.')
|
l = rel[1][0].split('.')
|
||||||
relTable = l[0]
|
relTable = l[0]
|
||||||
relField = l[1]
|
relField = l[1]
|
||||||
replaceFields = rel[1][1]
|
replaceFields = rel[1][1]
|
||||||
# print('reltable - ' + relTable)
|
|
||||||
#print('relfield - ' + relField)
|
|
||||||
#print('relrelation - ' + replaceFields)
|
|
||||||
return [relTable, relField, replaceFields]
|
return [relTable, relField, replaceFields]
|
||||||
return "q"
|
return "q"
|
||||||
|
|
||||||
@ -314,10 +300,6 @@ def insertDataIntoBD(dataList):
|
|||||||
global c, conn
|
global c, conn
|
||||||
dbConnect()
|
dbConnect()
|
||||||
tableName = dataList[0]
|
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)
|
qwery = 'INSERT INTO {} ('.format(tableName)
|
||||||
qweryData = ''
|
qweryData = ''
|
||||||
qweryField = ''
|
qweryField = ''
|
||||||
@ -326,30 +308,23 @@ def insertDataIntoBD(dataList):
|
|||||||
#print(fType)
|
#print(fType)
|
||||||
# проверяем если значение поля пустое то в запрос оно не включается
|
# проверяем если значение поля пустое то в запрос оно не включается
|
||||||
if item[1] != '':
|
if item[1] != '':
|
||||||
#qweryField = qweryField + item[0] + ','
|
|
||||||
qweryField = '{}{},'.format(qweryField,item[0])
|
qweryField = '{}{},'.format(qweryField,item[0])
|
||||||
if fType == 'integer':
|
if fType == 'integer':
|
||||||
#qweryData = qweryData + '' + item[1] + ','
|
|
||||||
qweryData = '{}{},'.format(qweryData,item[1])
|
qweryData = '{}{},'.format(qweryData,item[1])
|
||||||
elif fType == 'datetime':
|
elif fType == 'datetime':
|
||||||
# преобразуем дату всяко разно
|
# преобразуем дату всяко разно
|
||||||
dt = datetime.strptime(item[1], "%d.%m.%y %H:%M")
|
dt = datetime.strptime(item[1], "%d.%m.%y %H:%M")
|
||||||
item[1] = str(dt)
|
item[1] = str(dt)
|
||||||
#qweryData = qweryData + '\'' + item[1] + '\','
|
|
||||||
qweryData = "{}'{}',".format(qweryData,item[1])
|
qweryData = "{}'{}',".format(qweryData,item[1])
|
||||||
elif fType == 'date':
|
elif fType == 'date':
|
||||||
d = item[1].split('.')
|
d = item[1].split('.')
|
||||||
#myDate = d[2] + '-' + d[1] + '-' + d[1]
|
|
||||||
myDate = '{}-{}-{}'.format(d[2], d[1], d[1])
|
myDate = '{}-{}-{}'.format(d[2], d[1], d[1])
|
||||||
item[1] = str(myDate)
|
item[1] = str(myDate)
|
||||||
#qweryData = qweryData + '\'' + item[1] + '\','
|
|
||||||
qweryData = "{}'{}',".format(qweryData, item[1])
|
qweryData = "{}'{}',".format(qweryData, item[1])
|
||||||
else:
|
else:
|
||||||
#qweryData = qweryData + '\'' + item[1] + '\','
|
|
||||||
qweryData = "{}'{}',".format(qweryData, item[1])
|
qweryData = "{}'{}',".format(qweryData, item[1])
|
||||||
|
|
||||||
|
|
||||||
#qwery = qwery + qweryField.rstrip(',') + ')' + ' VALUES (' + qweryData.rstrip(',') + ');'
|
|
||||||
qwery = '{}{}) VALUES ({});'.format(qwery, qweryField.rstrip(','), qweryData.rstrip(','))
|
qwery = '{}{}) VALUES ({});'.format(qwery, qweryField.rstrip(','), qweryData.rstrip(','))
|
||||||
|
|
||||||
print(qwery)
|
print(qwery)
|
||||||
@ -385,20 +360,16 @@ def selectDataFromDB(tblName, fieldName, fieldValue):
|
|||||||
# составляем подзапрос и подменяем им поле в запросе
|
# составляем подзапрос и подменяем им поле в запросе
|
||||||
if db_type == "mysql":
|
if db_type == "mysql":
|
||||||
fieldReplace = fieldReplace.replace(",", ",' ',")
|
fieldReplace = fieldReplace.replace(",", ",' ',")
|
||||||
#subqwery = "(SELECT CONCAT(" + fieldReplace + ") FROM " + subqwery + " WHERE " + table1 + "." + field1 + "=" + tblName + "." + field + ") AS " + field
|
|
||||||
subqwery = '(SELECT CONCAT({}) FROM {} WHERE {}.{}={}.{}) AS {}'\
|
subqwery = '(SELECT CONCAT({}) FROM {} WHERE {}.{}={}.{}) AS {}'\
|
||||||
.format(fieldReplace, subqwery, table1, field1, tblName, field, field)
|
.format(fieldReplace, subqwery, table1, field1, tblName, field, field)
|
||||||
elif db_type == "sqlite":
|
elif db_type == "sqlite":
|
||||||
fieldReplace = fieldReplace.replace(",", " || ' ' ||")
|
fieldReplace = fieldReplace.replace(",", " || ' ' ||")
|
||||||
#subqwery = "(SELECT (" + fieldReplace + ") FROM " + subqwery +" WHERE "+ table1 + "." + field1 +"="+ tblName +"."+ field +") AS " + field
|
|
||||||
subqwery = '(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}'\
|
subqwery = '(SELECT ({}) FROM {} WHERE {}.{}={}.{}) AS {}'\
|
||||||
.format(fieldReplace, subqwery, table1, field1, tblName, field, field)
|
.format(fieldReplace, subqwery, table1, field1, tblName, field, field)
|
||||||
#print("---" + subqwery)
|
|
||||||
qwery = qwery.replace(field, 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)
|
qwery = '{} FROM {} WHERE {}={}'.format(qwery.rstrip(','), tblName, fieldName, fieldValue)
|
||||||
|
|
||||||
|
|
||||||
print(qwery)
|
print(qwery)
|
||||||
c.execute(qwery)
|
c.execute(qwery)
|
||||||
return c.fetchall()
|
return c.fetchall()
|
||||||
@ -435,11 +406,11 @@ def getTablesDescriptionOfName(tblName):
|
|||||||
def deleteRecordsFromDB(tableName, valueList):
|
def deleteRecordsFromDB(tableName, valueList):
|
||||||
global c, db_type, conn
|
global c, db_type, conn
|
||||||
qwery = 'DELETE FROM {} WHERE '.format(tableName)
|
qwery = 'DELETE FROM {} WHERE '.format(tableName)
|
||||||
#print(qwery)
|
#print(valueList)
|
||||||
subQwery=''
|
subQwery=''
|
||||||
i = 0
|
i = 0
|
||||||
for item in getFields(tableName):
|
for item in getFields(tableName):
|
||||||
print(item[0], item[1])
|
#print(item[0], item[1])
|
||||||
if item[1] == 'integer':
|
if item[1] == 'integer':
|
||||||
#subQwery = subQwery + item[0] + '=' + valueList[i] + ' AND '
|
#subQwery = subQwery + item[0] + '=' + valueList[i] + ' AND '
|
||||||
subQwery = '{}{}={} AND '.format(subQwery, item[0], valueList[i])
|
subQwery = '{}{}={} AND '.format(subQwery, item[0], valueList[i])
|
||||||
@ -449,11 +420,61 @@ def deleteRecordsFromDB(tableName, valueList):
|
|||||||
i += 1
|
i += 1
|
||||||
qwery += subQwery
|
qwery += subQwery
|
||||||
qwery = qwery.rstrip('AND ').replace("='None'", " IS NULL")
|
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)
|
print(qwery)
|
||||||
c.execute(qwery)
|
c.execute(qwery)
|
||||||
conn.commit()
|
conn.commit()
|
||||||
return
|
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()
|
#initDBstructure()
|
||||||
firstInit()
|
firstInit()
|
||||||
dbConnect()
|
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.QtCore import *
|
||||||
from PyQt5.QtGui import *
|
from PyQt5.QtGui import *
|
||||||
from PyQt5.QtWidgets import *
|
from PyQt5.QtWidgets import *
|
||||||
|
#from PyQt5.QtWidgets import (QMainWindow, QTextEdit, QAction, QFileDialog, QApplication)
|
||||||
|
#from PyQt5.QtGui import QIcon
|
||||||
|
|
||||||
#import pymysql
|
#import pymysql
|
||||||
import dm
|
import dm
|
||||||
@ -33,6 +35,7 @@ class MyTable(QTableWidget):
|
|||||||
def contextMenuEvent(self, event):
|
def contextMenuEvent(self, event):
|
||||||
Rmenu = QMenu(self)
|
Rmenu = QMenu(self)
|
||||||
addRecord = Rmenu.addAction("Добавить запись")
|
addRecord = Rmenu.addAction("Добавить запись")
|
||||||
|
editRecord = Rmenu.addAction("Редактировать запись")
|
||||||
delRecord = Rmenu.addAction("Удалить запись")
|
delRecord = Rmenu.addAction("Удалить запись")
|
||||||
showRelations = Rmenu.addAction("Показать связанные документы")
|
showRelations = Rmenu.addAction("Показать связанные документы")
|
||||||
action = Rmenu.exec_(self.mapToGlobal(event.pos()))
|
action = Rmenu.exec_(self.mapToGlobal(event.pos()))
|
||||||
@ -46,6 +49,13 @@ class MyTable(QTableWidget):
|
|||||||
elif action == addRecord:
|
elif action == addRecord:
|
||||||
print("Добавить запись ")
|
print("Добавить запись ")
|
||||||
addNewRecord()
|
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:
|
elif action == showRelations:
|
||||||
item = self.item(self.currentIndex().row(), self.currentIndex().column())
|
item = self.item(self.currentIndex().row(), self.currentIndex().column())
|
||||||
showRelationsRecords(self.currentIndex().column(), item.text())
|
showRelationsRecords(self.currentIndex().column(), item.text())
|
||||||
@ -69,6 +79,24 @@ class MyTable(QTableWidget):
|
|||||||
#print(self.item(row, i).text())
|
#print(self.item(row, i).text())
|
||||||
i += 1
|
i += 1
|
||||||
deleteRecord(self, row, self.dbTableName, valueList)
|
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):
|
class RelationDataView(QMainWindow):
|
||||||
@ -170,9 +198,13 @@ class EditForm(QMainWindow):
|
|||||||
lblList = []
|
lblList = []
|
||||||
editList = []
|
editList = []
|
||||||
|
|
||||||
def __init__(self, tblName, tblDescr):
|
def __init__(self, tblName, tblDescr, action):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.tblName = tblName
|
self.tblName = tblName
|
||||||
|
self.action = action
|
||||||
|
if action == 'edit':
|
||||||
|
self.setWindowTitle("Редактирование записи")
|
||||||
|
elif action == 'add':
|
||||||
self.setWindowTitle("Добавление записи")
|
self.setWindowTitle("Добавление записи")
|
||||||
#self.setGeometry(300, 300, 400, 400)
|
#self.setGeometry(300, 300, 400, 400)
|
||||||
scroll_widget = QWidget()
|
scroll_widget = QWidget()
|
||||||
@ -240,6 +272,7 @@ class EditForm(QMainWindow):
|
|||||||
edit.setValidator(integerValidator)
|
edit.setValidator(integerValidator)
|
||||||
else:
|
else:
|
||||||
edit = QLineEdit()
|
edit = QLineEdit()
|
||||||
|
|
||||||
# создаём список полей и соответсвующих им QEdit
|
# создаём список полей и соответсвующих им QEdit
|
||||||
self.widgetsList.append([fName, edit])
|
self.widgetsList.append([fName, edit])
|
||||||
|
|
||||||
@ -247,15 +280,15 @@ class EditForm(QMainWindow):
|
|||||||
hboxEdit.addWidget(lbl2)
|
hboxEdit.addWidget(lbl2)
|
||||||
hboxEdit.addWidget(edit)
|
hboxEdit.addWidget(edit)
|
||||||
# добавляем к полю кнопку для вызова связанных
|
# добавляем к полю кнопку для вызова связанных
|
||||||
print(fName)
|
#print(fName)
|
||||||
listRelationTableAndField = dm.getRelationsForField(tblName, fName)
|
listRelationTableAndField = dm.getRelationsForField(tblName, fName)
|
||||||
|
|
||||||
print(listRelationTableAndField)
|
#print(listRelationTableAndField)
|
||||||
if listRelationTableAndField != 'q':
|
if listRelationTableAndField != 'q':
|
||||||
tableRelation = listRelationTableAndField[0]
|
tableRelation = listRelationTableAndField[0]
|
||||||
fieldRelation = listRelationTableAndField[1]
|
fieldRelation = listRelationTableAndField[1]
|
||||||
replaceField = listRelationTableAndField[2]
|
replaceField = listRelationTableAndField[2]
|
||||||
print(tableRelation + '-' + fieldRelation +'-'+replaceField)
|
#print(tableRelation + '-' + fieldRelation +'-'+replaceField)
|
||||||
btnRelations = QPushButton('...')
|
btnRelations = QPushButton('...')
|
||||||
btnRelations.setFixedWidth(30)
|
btnRelations.setFixedWidth(30)
|
||||||
# добавляем название виджета в список соответсвия кнопок и таблиц БД
|
# добавляем название виджета в список соответсвия кнопок и таблиц БД
|
||||||
@ -284,7 +317,10 @@ class EditForm(QMainWindow):
|
|||||||
listFieldData.append([item[0], item[1].text()])
|
listFieldData.append([item[0], item[1].text()])
|
||||||
listData.append(listFieldData)
|
listData.append(listFieldData)
|
||||||
#print(listData)
|
#print(listData)
|
||||||
|
if self.action == 'add':
|
||||||
dm.insertDataIntoBD(listData)
|
dm.insertDataIntoBD(listData)
|
||||||
|
elif self.action == 'edit':
|
||||||
|
dm.editDataIntoBD(listData)
|
||||||
self.close()
|
self.close()
|
||||||
# выбираем данные для связанной таблицы
|
# выбираем данные для связанной таблицы
|
||||||
def openRelationTable(self):
|
def openRelationTable(self):
|
||||||
@ -356,29 +392,38 @@ def addDataIntoTable(dbTableName, tblDataWidget, data='NULL'):
|
|||||||
dbFieldRelationValueList = []
|
dbFieldRelationValueList = []
|
||||||
for key in data:
|
for key in data:
|
||||||
n = 0
|
n = 0
|
||||||
#print(fieldNames, '\n', key)
|
print(key)
|
||||||
for item in key:
|
for item in key:
|
||||||
#print(m, n, item)
|
|
||||||
listRelationTableAndField = dm.getRelationsForField(dbTableName, fieldNames[n][0])
|
listRelationTableAndField = dm.getRelationsForField(dbTableName, fieldNames[n][0])
|
||||||
#print('--->', fieldNames[n][1])
|
|
||||||
if listRelationTableAndField != 'q':
|
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:
|
if itemString:
|
||||||
#print('--->',itemString.groups())
|
|
||||||
newitem = QTableWidgetItem(itemString.groups()[1])
|
newitem = QTableWidgetItem(itemString.groups()[1])
|
||||||
dbFieldRelationValueList.append([newitem, m, n, itemString.groups()[0], itemString.groups()[1]])
|
dbFieldRelationValueList.append([newitem, m, n, itemString.groups()[0], itemString.groups()[1]])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
newitem = QTableWidgetItem(str(item))
|
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)
|
tblDataWidget.setItem(m, n, newitem)
|
||||||
n += 1
|
n += 1
|
||||||
m += 1
|
m += 1
|
||||||
#print(dbFieldRelationValueList)
|
|
||||||
# Показ менб и панели инструментов
|
# Показ меню и панели инструментов
|
||||||
def showMenuToolbar(window):
|
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 = QAction(QIcon('img/new.gif'), 'Добавить', window)
|
||||||
newAction.setShortcut('Ins')
|
newAction.setShortcut('Ins')
|
||||||
newAction.setStatusTip('Добавить')
|
newAction.setStatusTip('Добавить')
|
||||||
@ -387,45 +432,46 @@ def showMenuToolbar(window):
|
|||||||
deleteAction = QAction(QIcon('img/delete.gif'), 'Удалить', window)
|
deleteAction = QAction(QIcon('img/delete.gif'), 'Удалить', window)
|
||||||
deleteAction.setShortcut('Del')
|
deleteAction.setShortcut('Del')
|
||||||
deleteAction.setStatusTip('Удалить')
|
deleteAction.setStatusTip('Удалить')
|
||||||
# deleteAction.triggered.connect(window.qqqq)
|
|
||||||
|
|
||||||
exitAction = QAction(QIcon('img/exit.gif'), 'Выход', window)
|
exitAction = QAction(QIcon('img/exit.gif'), 'Выход', window)
|
||||||
exitAction.setShortcut('Ctrl+Q')
|
exitAction.setShortcut('Ctrl+Q')
|
||||||
exitAction.setStatusTip('Выход')
|
exitAction.setStatusTip('Выйти')
|
||||||
exitAction.triggered.connect(window.close)
|
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 = QAction(QIcon('img/cut.gif'), 'Вырезать', window)
|
||||||
cutAction.setShortcut('Ctrl+X')
|
cutAction.setShortcut('Ctrl+X')
|
||||||
cutAction.setStatusTip('Вырезать')
|
cutAction.setStatusTip('Вырезать')
|
||||||
# cutAction.triggered.connect(window.close)
|
|
||||||
|
|
||||||
copyAction = QAction(QIcon('img/copy.gif'), 'Копировать', window)
|
copyAction = QAction(QIcon('img/copy.gif'), 'Копировать', window)
|
||||||
copyAction.setShortcut('Ctrl+С')
|
copyAction.setShortcut('Ctrl+С')
|
||||||
copyAction.setStatusTip('Копировать')
|
copyAction.setStatusTip('Копировать')
|
||||||
# copyAction.triggered.connect(window.close)
|
|
||||||
|
|
||||||
pasteAction = QAction(QIcon('img/paste.gif'), 'Вставить', window)
|
pasteAction = QAction(QIcon('img/paste.gif'), 'Вставить', window)
|
||||||
pasteAction.setShortcut('Ctrl+V')
|
pasteAction.setShortcut('Ctrl+V')
|
||||||
pasteAction.setStatusTip('Вставить')
|
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.setShortcut('Ctrl+F')
|
||||||
findAction.setStatusTip('Искать')
|
findAction.setStatusTip('Искать')
|
||||||
# findAction.triggered.connect(window.close)
|
|
||||||
|
|
||||||
printAction = QAction(QIcon('img/print.gif'), 'Печатать', window)
|
printAction = QAction(QIcon('img/print.gif'), 'Печатать', window)
|
||||||
printAction.setShortcut('Ctrl+P')
|
printAction.setShortcut('Ctrl+P')
|
||||||
printAction.setStatusTip('Печатать')
|
printAction.setStatusTip('Печатать')
|
||||||
# printAction.triggered.connect(window.close)
|
|
||||||
|
|
||||||
window.statusBar()
|
window.statusBar()
|
||||||
|
|
||||||
menubar = window.menuBar()
|
menubar = window.menuBar()
|
||||||
fileMenu = menubar.addMenu('&Файл')
|
fileMenu = menubar.addMenu('&Файл')
|
||||||
|
fileMenu.addAction(openFileAction)
|
||||||
fileMenu.addAction(newAction)
|
fileMenu.addAction(newAction)
|
||||||
fileMenu.addAction(deleteAction)
|
fileMenu.addAction(deleteAction)
|
||||||
fileMenu.addAction(printAction)
|
fileMenu.addAction(printAction)
|
||||||
|
fileMenu.addAction(structureAction)
|
||||||
fileMenu.addAction(exitAction)
|
fileMenu.addAction(exitAction)
|
||||||
|
|
||||||
editMenu = menubar.addMenu('&Редактирование')
|
editMenu = menubar.addMenu('&Редактирование')
|
||||||
@ -439,6 +485,7 @@ def showMenuToolbar(window):
|
|||||||
# toolbar = window.addToolBar('Редактирование')
|
# toolbar = window.addToolBar('Редактирование')
|
||||||
|
|
||||||
toolbar = window.addToolBar('Панель инструментов')
|
toolbar = window.addToolBar('Панель инструментов')
|
||||||
|
#toolbar.addAction(openFileAction)
|
||||||
toolbar.addAction(newAction)
|
toolbar.addAction(newAction)
|
||||||
toolbar.addAction(deleteAction)
|
toolbar.addAction(deleteAction)
|
||||||
toolbar.addAction(copyAction)
|
toolbar.addAction(copyAction)
|
||||||
@ -457,7 +504,7 @@ def addNewRecord():
|
|||||||
tblName = i[0]
|
tblName = i[0]
|
||||||
|
|
||||||
#print(tblName)
|
#print(tblName)
|
||||||
editForm = EditForm(tblName, tblDescr)
|
editForm = EditForm(tblName, tblDescr, 'add')
|
||||||
editForm.show()
|
editForm.show()
|
||||||
#editForm.setParent(listDBTables)
|
#editForm.setParent(listDBTables)
|
||||||
#editForm.show()
|
#editForm.show()
|
||||||
@ -497,27 +544,58 @@ def showRelationsRecords(fieldIndex, fieldValue):
|
|||||||
addDataIntoTable(tbl, tblRelationsData, qweryResult)
|
addDataIntoTable(tbl, tblRelationsData, qweryResult)
|
||||||
# пишем название активной таблицы БД в строку статуса
|
# пишем название активной таблицы БД в строку статуса
|
||||||
tblRelationsData.setStatusTip(tbl)
|
tblRelationsData.setStatusTip(tbl)
|
||||||
|
# Удаление записи
|
||||||
def deleteRecord(tableWidget, row, dbTableName, valueList):
|
def deleteRecord(tableWidget, row, dbTableName, valueList):
|
||||||
global dbFieldRelationValueList
|
global dbFieldRelationValueList
|
||||||
#print(tableWidget, row, dbTableName, valueList)
|
|
||||||
#print(self.columnCount())
|
|
||||||
i = 0
|
i = 0
|
||||||
#print(valueList)
|
|
||||||
for val in valueList:
|
for val in valueList:
|
||||||
#print(tableWidget.item(row, i))
|
|
||||||
#print('Значение из таблицы-->',valueList[i])
|
|
||||||
for item in dbFieldRelationValueList:
|
for item in dbFieldRelationValueList:
|
||||||
if item[0] == tableWidget.item(row, i):
|
if item[0] == tableWidget.item(row, i):
|
||||||
#print(item[0])
|
|
||||||
#print('еще значение',tableWidget.item(row, i).text(), item[0])
|
|
||||||
value = item[3]
|
value = item[3]
|
||||||
valueList.pop(i)
|
valueList.pop(i)
|
||||||
valueList.insert(i, item[3])
|
valueList.insert(i, item[3])
|
||||||
|
|
||||||
i += 1
|
i += 1
|
||||||
#print(valueList)
|
|
||||||
dm.deleteRecordsFromDB(dbTableName, 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():
|
def main():
|
||||||
global dbTablesList, listDBTables, tabRelationsData, dbFieldRelationValueList
|
global dbTablesList, listDBTables, tabRelationsData, dbFieldRelationValueList
|
||||||
@ -555,12 +633,12 @@ def main():
|
|||||||
print(dm.getTablesNameOfDescription(listDBTables.model().data(listDBTables.currentIndex())))
|
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.setWindowTitle('Data manipulator')
|
||||||
mainWin.show()
|
mainWin.show()
|
||||||
|
|
||||||
return app.exec_()
|
return app.exec_()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
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_())
|
|
Loading…
x
Reference in New Issue
Block a user