Source code for geodrill.geoDB.interfaceDB

# -*- coding: utf-8 -*-
"""
===============================================================================
    Copyright © 2021  Kouadio K.Laurent
    
    This file is part of pyCSAMT.
    
    pyCSAMT is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    pyCSAMT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.
    
    You should have received a copy of the GNU Lesser General Public License
    along with pyCSAMT.  If not, see <https://www.gnu.org/licenses/>.

===============================================================================  
.. _module-Interface::`geodrill.geoDB.interfaceDB`
 
    :synopsis: Specially dedicate to Manage SQL 
Created on Tue Oct 13 15:28:57 2020

@author: @Daniel03
"""
import os, shutil 

import warnings
import pandas as pd 
# from pg8000 import DBAPI

import sqlite3 as sq3 

#
try : 
    from csamtpy.utils  import exceptions as CSex
    from csamtpy.utils._csamtpylog import csamtpylog
    _logger=csamtpylog.get_csamtpy_logger(__name__)
except :
    pass


[docs]class ManageDB(object) : """ build a datable postgre Sql from dict_app.py simple way to make a transit between two objects One object dict_app to populate DataBase Arguments ------------ **db_name** : str name of dataBase **db_host** : st path to database ==================== ============== ==================================== Attributes Type Explanation ==================== ============== ==================================== connex object DataBase connection curs object Database cursor ==================== ============== ==================================== ========================== =============================================== Methods Explanation ========================== =============================================== dicT_sqlDB send infos as dictionnary to dataBase execute req execute a sql_request drop_TableDB drop all Tables in sql memory DB or single Table closeDB close after requests the connection and the cursor commit transfer the data to DataBase. if not the data will still in the cursor and not in the dataBase print_last_Query print the last operating system export_req export the request on datasheet like excelsheet . ========================== =============================================== :Example: >>> from sqlrequests import SqlQ >>> path= os.getcwd() >>> nameofDB='memory.sq3' >>> manDB=ManageDB(db_name=nameofDB, ... db_host=path) ... print(SqlQ.sql_req[-1]) ... manDB.executeReq(SqlQ.sql_req[2]) ... ss=manDB.print_last_Query() ... print(ss) ... manDB.export_req(SqlQ.sql_req[-1], export_type='.csv') ... manDB.dicT_sqlDB(dictTables=Glob.dicoT, visualize_request=False) """ def __init__(self, db_name =None, db_host=None): self._logging=csamtpylog.get_csamtpy_logger(self.__class__.__name__) self.db_host=db_host self.db_name=db_name if self.db_name is not None : self.connect_DB()
[docs] def connect_DB(self, db_host=None , db_name=None): """ Create sqqlite Database :param db_host: DataBase location path :type db_host: str :param db_name: str , DataBase name :type db_name: str """ if db_host is not None : self.db_host = db_host if db_name is not None : self.db_name = db_name mess= '' if self.db_name is None : mess ='Could not create a DataBase ! Need to input the DataBase name.' if self.db_host is None : mess ='Could not create a DataBase : No "{0}" Database path detected.'\ ' Need to input the path for Database location.'.format(self.db_name) if mess !='': warnings.warn(mess) self._logging.error(mess) # raise CSex.pyCSAMTError_SQL(mess ) # try to connect to de dataBase if self.db_host is not None : try : self.connexDB=sq3.connect(os.path.join(self.db_host, self.db_name)) except : warnings.warn("Connection to SQL %s failed !." %self.db_name) # raise CSex.pyCSAMTError_SQL_manager('Connection to SQL dataBase failed ,Please try again.') self.success=0 else : self.curs =self.connexDB.cursor() self.success=1
[docs] def dicT_sqlDB(self, dicTables, **kwargs): """ Method to create Table for sqlDataBase . Enter Data to DataBase from dictionnary. Interface objet : Database _Dictionnary to see how dicTable is arranged , may consult dict_app module Parameters ---------- * dictTables : dict Rely on dict_app.py module. it populates the datababse from dictionnay app Returns --------- str execute queries from dict_app :Example : >>> mDB=GestionDB (dbname='memory.sq3, ... db_host =os.getcwd()') >>> mDB.dicT_sqlDB(dicTables=Glob.dicoT, ... visualize_request=False) >>> ss=mB.print_last_query() >>> print(ss) """ visual_req=kwargs.pop('visualize_request', False) field_dico ={'i':'INTEGER',"t":"TEXT",'b':'BOOL', 'd': 'HSTORE',"k": "SERIAL", 'n':'NULL', "f": 'REAL','s':'VARCHAR','date':'date', 'by':'BYTHEA','l':'ARRAY', } for table in dicTables: req="CREATE TABLE %s (" % table pk="" for ii, descrip in enumerate(dicTables[table]): field=descrip[0] tfield=descrip[1] # Type of field # for keys in field_dico.keys(): if tfield in field_dico.keys(): # if tfield == keys : typefield=field_dico[tfield] else : # sql vriable nom :'s':'VARCHAR' typefield='VARCHAR(%s)'%tfield req= req+'%s %s, ' %(field, typefield) if pk=='': req=req [:-2] + ")" # delete the last ',' on req. else : req =req +"CONSTRAINT %s_pk PRIMARY KEYS(%s))" %(pk,pk) if visual_req is True : # print the request built . print(req) try : self.executeReq(req) except : pass # the case where the table already exists. return req
[docs] def executeReq(self, query, param=None): """ Execute request of dataBase with detection of error. Parameters ----------- * query : str sql_query * param : str Default is None . raise : ------- layout the wrong sql queries . return : ------- int 1, the request has been successuful run . :Example: >>> for keys in Glob.dicoT.keys(): ... reqst='select * from %s'%keys >>> ss=manageDB.executeReq(query=reqst) >>> print(ss) """ try : if param is None : self.curs.execute(query)# param) else : self.curs.execute(query, param) except: warnings.warn(f'Request SQL {query} failed. May trouble of SQL server connexion. '\ 'Please try again later ') # raise (f'Request SQL {query}executed failed',err) return 0 else : return 1
[docs] def drop_TableDB(self, dicTables, drop_table_name=None , drop_all=False): """ Drop the name of table on dataBase or all databases. Parameters ---------- * dicTables : dict application dictionnary. Normally provide from dict_app.py module * drop_table_name : str, optional field name of dictionnay (Table Name). The default is None. * drop_all : Bool, optional Must select if you need to drop all table. The default is False. Raises ------ Exception : Errors occurs ! . """ if drop_all is False and drop_table_name is None : raise 'Must be input at least one name contained of keys in the dicT_app' elif drop_all is True : for keys in dicTables.keys(): req="DROP TABLE %s" %keys self.executeReq(req) elif drop_table_name is not None : if drop_table_name in dicTables.keys(): req="DROP TABLE %s" % drop_table_name else : raise'No such name in the dictionnary application Table!'\ 'Dict_app keys Tables Names are : ¨{0}'.format(dicTables.keys()) self.executeReq(req) self.connexDB.commit()
[docs] def closeDB(self): """ simple method to close Database. """ if self.connexDB : # self.curs.close() self.connexDB.close()
[docs] def commit(self) : """ special commit method for the database when cursor and connexion are still open. """ if self.connexDB : self.connexDB.commit()
[docs] def print_query(self, column_name=None ) : """ return the result of the previous query. Parameters : ------------ * query_table_nam : str name of table to fetch colounm data . """ if column_name is not None : return self.curs.fetchone() else : return self.curs.fetchall()
[docs] def export_req(self, query =None , export_type='.csv', **kwargs): """ method to export data from DataBase Parameters ---------- * query : str, optional Sql requests. You may consult sql_request files. The default is None. * export_type : Str, optional file extension. if None , it will export on simple file. The default is '.csv'. * kwargs : str Others parameters. Raises ------ Exception Print wrong sqlrequests. :Example: >>> from sqlrequests import SqlQ >>> manageDB.executeReq(SqlQ.sql_req[2]) >>> ss=manageDB.print_last_Query() >>> print(ss) >>> manageDB.export_req(SqlQ.sql_req[-1], export_type='.csv', ) """ exportfolder=kwargs.pop('savefolder','savefiles') filename =kwargs.pop('filename','req_file') indexfile=kwargs.pop('index',False) headerfile=kwargs.pop("header",True) if query is None : raise Exception ("SQL requests (%s) no found ! Please Try to put "\ " your sql_requests"% query) elif query is not None : df_sql=pd.read_sql_query(query,self.connexDB) if filename.endswith('.csv'): export_type ='.csv' filename=filename[:-4] elif filename.endswith(('.xlxm', '.xlsx', '.xlm')): export_type='.xlsx' filename=filename[:-5] else : assert export_type is not None , 'Must input the type to export file.'\ ' it maybe ".csv" or ".xlsx"' #-----export to excel sheet if export_type in ['csv','.csv', 'comma delimited', 'comma-separated-value','comma sperated value', 'comsepval']: # export to excelsheet: df_sql.to_csv(filename+'.csv', header=headerfile, index =indexfile,sep=',', encoding='utf8') sql_write =1 elif export_type in ['xlsx','.xlsx', 'excell', 'Excell','excel','Excel','*.xlsx']: df_sql.to_excel(filename+'.xlsx',sheet_name=filename[:-3], index =indexfile) sql_write =0 #wite a new folder if exportfolder is not None : try : os.mkdir('{0}'.format(exportfolder)) except OSError as e : print(os.strerror(e.errno)) sql_path=os.getcwd() savepath=sql_path+'/{0}'.format(exportfolder) if sql_write ==1 : shutil.move(filename +'.csv', savepath) print('---> outputDB_file <{0}.csv> has been written.'.format(filename)) elif sql_write ==0 : shutil.move(filename +'.xlsx',savepath) print('---> outputDB_file <{0}.xlsx> has been written.'.format(filename))