data-manipulation/dm.py
2017-03-23 16:35:44 +03:00

396 lines
16 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-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
config = configparser.RawConfigParser()
# проверяем тип ОС
if os.name == "nt":
cfg_dir = os.path.join(os.getenv("USERPROFILE"), ".dm")
elif os.name == "posix":
cfg_dir = os.path.join(os.getenv("HOME"), ".dm")
# определим каталог для конфигруции и создадим если его нет
if os.path.isdir(cfg_dir):
print(cfg_dir + " already exists")
else:
os.mkdir(cfg_dir)
cfg_file = os.path.join(cfg_dir, 'dm.cfg')
# создадим файл конфигурации
config.add_section('DataBase')
config.set('DataBase', 'db_type', 'mysql')
config.set('DataBase', 'db_hostname', 'localhost')
config.set('DataBase', 'db_name', 'dm')
config.set('DataBase', 'db_user', 'dm')
config.set('DataBase', 'db_password', 'password')
config.add_section('Directory')
config.set('Directory', 'work_dir', cfg_dir)
config.set('Directory', 'template_dir', os.path.join(cfg_dir, 'db_template'))
# Если конфиг уже есть читаем его если нет, создаем и потом читаем
if os.path.isfile(cfg_file):
config.read(cfg_file)
else:
# Запись конфигурации в файл 'example.cfg'
with open(cfg_file, 'w') as configfile:
config.write(configfile)
configfile.close()
config.read(cfg_file)
work_dir = config.get('Directory', 'work_dir')
template_dir = config.get('Directory', 'template_dir')
db_type = config.get('DataBase', 'db_type')
db_hostname = config.get('DataBase', 'db_hostname')
if db_type == 'sqlite':
db_name = os.path.join(work_dir, config.get('DataBase', 'db_name'))
else:
db_name = config.get('DataBase', 'db_name')
db_user = config.get('DataBase', 'db_user')
db_password = config.get('DataBase', 'db_password')
# Создаём нужные каталоги
if os.path.isdir(work_dir):
print(work_dir + " already exists")
else:
os.mkdir(work_dir)
if os.path.isdir(template_dir):
print(template_dir + " already exists")
else:
os.mkdir(template_dir)
# копируем и читаем файл шаблон БД
template_file = os.path.join(template_dir, 'tables.json')
if os.path.isfile(template_file):
print("Template file already exists")
else:
shutil.copy('tables.json', template_file)
def dbConnect():
global c, db_type, db_hostname, db_user, db_password, db_name
if db_type == "mysql":
import pymysql
conn = pymysql.connect(
db=db_name,
user=db_user,
passwd=db_password,
host=db_hostname,
charset='utf8')
elif db_type == "sqlite":
import sqlite3
conn = sqlite3.connect(db_name)
else:
print(db_type + " database type does`t support")
exit()
#print(conn)
c = conn.cursor()
return c
def createTables(tbl_list):
global tbl_descr_list, tbl_struct_list, c, db_type
i = 0
tbl_names_list = []
tbl_descr_list = []
tbl_struct_list = []
while i < len(tbl_list):
one_Table_descr = []
one_Table_struct = []
one_Table_relation = []
tbl_descr = tbl_list[i]["tableDescription"]
tbl_name = tbl_list[i]["tableName"]
#field_list = tbl_list[i]["fieldList"][i].keys()
tbl_names_list.append([tbl_name, tbl_descr])
one_Table_descr.append(tbl_name)
one_Table_struct.append(tbl_name)
x = 0
# список всех полей таблицы
qwery_create = "CREATE TABLE IF NOT EXISTS " + tbl_name + " ("
index = ""
field_names_list = []
struct_fields_list = []
# формируем запрос в зависимости от типа БД
if db_type == 'mysql':
while x < len(tbl_list[i]["fieldList"]):
if tbl_list[i]["fieldList"][x]["autoIncrement"] == "yes":
auto_increment = " AUTO_INCREMENT, "
else:
auto_increment = ", "
qwery_create = qwery_create + tbl_list[i]["fieldList"][x]["fName"] + " " + \
tbl_list[i]["fieldList"][x]["fType"] + auto_increment
if tbl_list[i]["fieldList"][x]["index"] == "PRIMARY KEY":
index = "PRIMARY KEY(" + tbl_list[i]["fieldList"][x]["fName"] + ")"
field_names_list.append(
[tbl_list[i]["fieldList"][x]["fName"], tbl_list[i]["fieldList"][x]["fDescription"]])
# struct_fields_list.append(tbl_list[i]["fieldList"][x]["fName"])
struct_fields_list.append(
[tbl_list[i]["fieldList"][x]["fName"], fieldTypeConvert(tbl_list[i]["fieldList"][x]["fType"]), ])
if tbl_list[i]["fieldList"][x]["relation"]:
relation_list = [tbl_list[i]["fieldList"][x]["fName"]]
relation_list.append(tbl_list[i]["fieldList"][x]["relation"])
one_Table_relation.append(relation_list)
x = x + 1
qwery_create = qwery_create + index + ");"
elif db_type == 'sqlite':
while x < len(tbl_list[i]["fieldList"]):
if tbl_list[i]["fieldList"][x]["autoIncrement"] == "yes":
auto_increment = " AUTOINCREMENT,"
else:
auto_increment = ", "
if tbl_list[i]["fieldList"][x]["index"] == "PRIMARY KEY":
index = " PRIMARY KEY"
else:
index = ''
qwery_create = qwery_create + tbl_list[i]["fieldList"][x]["fName"] + ' ' + \
tbl_list[i]["fieldList"][x]["fType"] + index + auto_increment
field_names_list.append([tbl_list[i]["fieldList"][x]["fName"], tbl_list[i]["fieldList"][x]["fDescription"]])
# struct_fields_list.append(tbl_list[i]["fieldList"][x]["fName"])
struct_fields_list.append(
[tbl_list[i]["fieldList"][x]["fName"], fieldTypeConvert(tbl_list[i]["fieldList"][x]["fType"]), ])
if tbl_list[i]["fieldList"][x]["relation"]:
relation_list = [tbl_list[i]["fieldList"][x]["fName"]]
relation_list.append(tbl_list[i]["fieldList"][x]["relation"])
one_Table_relation.append(relation_list)
x = x + 1
qwery_create = qwery_create.strip(', ') + ");"
one_Table_struct.append(struct_fields_list)
one_Table_struct.append(one_Table_relation)
one_Table_descr.append(field_names_list)
i = i + 1
tbl_descr_list.append(one_Table_descr)
tbl_struct_list.append(one_Table_struct)
print(qwery_create)
c.execute(qwery_create)
return tbl_names_list
def initDBstructure():
global tbl_descr_list, 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)
return tblNamesList
# выборка данных из заданной таблицы
def selectData(tbl):
global tbl_struct_list, c, db_type
# если юольше 1 поля добавить CONCAT
qwery = "SELECT "
subqwery = ""
for item in tbl_struct_list:
if item[0] == tbl:
for field in item[1]:
field = field[0]
qwery = qwery + field + ","
for rel in item[2]:
field = rel[0]
field_rel = rel[1][0]
field_replace = rel[1][1]
#field_replace = field_replace.replace(",", ",' ',")
#field_replace = field_replace.replace(",", " || ")
# определяем название таблицы для вложенного запроса
table1 = field_rel.split('.')[0]
field1 = field_rel.split('.')[1]
if table1 == tbl:
table1 = table1 + "_1"
subqwery = tbl + " AS " +table1
else:
subqwery = table1
# составляем подзапрос и подменяем им поле в запросе
if db_type == "mysql":
field_replace = field_replace.replace(",", ",' ',")
subqwery = "(SELECT CONCAT(" + field_replace + ") FROM " + subqwery + " WHERE " + table1 + "." + field1 + "=" + tbl + "." + field + ") AS " + field
elif db_type == "sqlite":
field_replace = field_replace.replace(",", " || ' ' ||")
subqwery = "(SELECT (" + field_replace + ") FROM " + subqwery +" WHERE "+ table1 + "." + field1 +"="+ tbl +"."+ field +") AS " + field
qwery = qwery.replace(field, subqwery)
qwery = qwery.rstrip(',') + " FROM " + tbl + " LIMIT 10000"
print(qwery)
c.execute(qwery)
return c.fetchall()
# получаем на вход имя таблицы и возвращаем список заголовков полей
def getTableStructure(tbl):
global tbl_descr_list, tbl_struct_list
#print(tbl_descr_list)
#print(tbl_struct_list)
for item in tbl_descr_list:
if item[0] == tbl:
return item[1]
# Получаем список названий полей и типов для заданной таблицы
def getFields(tbl):
global tbl_descr_list, tbl_struct_list
#print(tbl_descr_list)
#print(tbl_struct_list)
for item in tbl_struct_list:
if item[0] == tbl:
#print(item[1])
return item[1]
# Ищем описание поля по его названию и возвращаем.
def getFieldDescription(tbl, field):
global tbl_descr_list, tbl_struct_list
for item in tbl_descr_list:
if item[0] == tbl:
for i in item[1]:
if i[0] == field:
fName = i[1]
return fName
return "null"
def fieldTypeConvert(ftype):
# разбираем строку на тип и длину
ftype = str.lower(ftype)
line = re.search("(.+?)\(([0-9]+)\)", ftype)
if line:
fType = line.groups()[0]
fLength = line.groups()[1]
if fType == 'int' or fType == 'integer':
fType = 'integer'
elif fType == 'char' or fType == 'varchar':
fType = 'character'
else:
fType = ftype
return fType
def getFieldType(tbl, field):
global tbl_descr_list, tbl_struct_list
#print(tbl_descr_list)
#print(tbl_struct_list)
for item in tbl_struct_list:
if item[0] == tbl:
for i in item[1]:
if i[0] == field:
fType = i[1]
return fType
#print(item[1])
#return item[1]
# добавление записи в БД на вход принимает список вида:
# [table [['field_1', 'значение'], ['field_2', 'значение'],....., ['field_n', 'значение']]]
def insertDataIntoBD(dataList):
global c
dbConnect()
tableName = dataList[0]
#datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M")
qwery = 'INSERT INTO ' + tableName + ' ('
qweryData = ''
qweryField = ''
for item in dataList[1]:
fType = getFieldType(tableName, item[0])
#print(fType)
qweryField = qweryField + item[0] + ','
if fType == 'integer':
qweryData = qweryData + '' + item[1] + ','
elif fType == 'datetime':
#преобразуем дату всяко разно
dt = datetime.strptime(item[1], "%d.%m.%Y %H:%M")
item[1] = str(dt)
qweryData = qweryData + '\'' + item[1] + '\','
elif fType == 'date':
d = item[1].split('.')
myDate = d[2] + '-' + d[1] + '-' + d[1]
item[1] = str(myDate)
qweryData = qweryData + '\'' + item[1] + '\','
else:
qweryData = qweryData + '\'' + item[1] + '\','
qwery = qwery + qweryField.rstrip(',') + ')' + ' VALUES (' + qweryData.rstrip(',') + ');'
#print(qwery)
c.execute(qwery)
#c.close()
return
# Выборка данных по значению
# принимает на вход название таблицы, назване поля, значение этого поля
def selectDataFromDB(tblName, fieldName, fieldValue):
global tbl_struct_list, c, db_type
qwery = "SELECT "
subqwery = ""
for item in tbl_struct_list:
if item[0] == tblName:
for field in item[1]:
field = field[0]
qwery = qwery + field + ","
for rel in item[2]:
field = rel[0]
fieldRel = rel[1][0]
fieldReplace = rel[1][1]
#field_replace = field_replace.replace(",", ",' ',")
#field_replace = field_replace.replace(",", " || ")
# определяем название таблицы для вложенного запроса
table1 = fieldRel.split('.')[0]
field1 = fieldRel.split('.')[1]
if table1 == tblName:
table1 = table1 + "_1"
subqwery = tblName + " AS " +table1
else:
subqwery = table1
# составляем подзапрос и подменяем им поле в запросе
if db_type == "mysql":
fieldReplace = fieldReplace.replace(",", ",' ',")
subqwery = "(SELECT CONCAT(" + fieldReplace + ") FROM " + subqwery + " WHERE " + table1 + "." + field1 + "=" + tblName + "." + field + ") AS " + field
elif db_type == "sqlite":
print(db_type)
print(fieldReplace)
fieldReplace = fieldReplace.replace(",", " || ' ' ||")
print(fieldReplace)
subqwery = "(SELECT (" + fieldReplace + ") FROM " + subqwery +" WHERE "+ table1 + "." + field1 +"="+ tblName +"."+ field +") AS " + field
print("---" + subqwery)
qwery = qwery.replace(field, subqwery)
#qwery = qwery.rstrip(',') + " FROM " + tblName + " LIMIT 10000"
qwery = qwery.rstrip(',') + " FROM " + tblName + " WHERE " + fieldName + '=' + fieldValue
print(qwery)
c.execute(qwery)
return c.fetchall()
def selectRelationsDataFromDB(tblSearch, fieldName, fieldValue):
global tbl_struct_list, c, db_type
#print("Ищем связи для:" +tblSearch +','+ fieldName +','+fieldValue)
#print(tbl_struct_list)
searchField = tblSearch + '.' + fieldName
dataList = []
for item in tbl_struct_list:
#print(item)
tblName = item[0]
for field in item[1]:
field = field[0]
for rel in item[2]:
if rel[1][0] == searchField:
#print("таблица:" + tblName + "поле:"+ rel[0] + 'Значение:' + fieldValue)
data = selectDataFromDB(tblName, rel[0], fieldValue)
#print(data)
dataList.append([tblName, data])
return dataList
# Ищем название таблицы по её описанию
def getTablesNameOfDescription(tblDescr):
global tblNamesList
for i in tblNamesList:
if i[1] == tblDescr:
return(i[0])
# Ищем описание таблицы по её названию
def getTablesDescriptionOfName(tblName):
global tblNamesList
for i in tblNamesList:
if i[0] == tblName:
return(i[1])
#initDBstructure()
firstInit()
dbConnect()