1. 程式人生 > >孤荷凌寒自學python第四十七天通用跨資料庫同一資料庫中複製資料表函式

孤荷凌寒自學python第四十七天通用跨資料庫同一資料庫中複製資料表函式

孤荷凌寒自學python第四十七天通用跨資料庫同一資料庫中複製資料表函式

 

(完整學習過程螢幕記錄視訊地址在文末)

今天繼續建構自感覺用起來順手些的自定義模組和類的程式碼。

今天打算完成的是通用的(至少目前操作四種資料庫)在同一資料庫內複製資料表的方法函式。

 

此設想最初我自我感覺都非常簡單,然而事實是關係型資料庫統一使用的sql語言在各家其實是完全不同的!

 

一、瞭解清楚了我目前研究的四種關係型資料庫對同一資料庫中資料表的複製操作的sql語句的異同也效果侷限

(一)Access 資料庫與mssql資料庫

access資料庫一般是作為輕量級的桌面級關係型資料庫使用的;

而mssql是微軟出品的大型商用伺服器型關係資料庫。

它們的複製資料表的操作sql語句一樣如下:

1.只複製資料表的結構而不復制源表的資料

select * into [目標表] from [源表] where 1=2;

最後的【where 1=2】就是限制連同資料一起復制的條件式,只要條件式返回的布林值為false即可。

2.要複製資料表結構與所有資料

select * into [目標表] from [源表];

 

【注意】:通過這樣的方式複製的資料表,目標表中雖然完整的複製了源表的所有列的型別、大小等資訊,卻唯獨不會包含各列是否是【主鍵】的資訊。

這其實也就是說複製已經基本失敗了。

 

(二)sqlite資料庫

sqlite是本地化的輕量級關係型資料庫。

它的複製程式碼如下

1.只複製資料表的結構而不復制源表的資料

CREATE TABLE [目標表] AS SELECT * FROM [源表] WHERE 1=2;

最後的【where 1=2】就是限制連同資料一起復制的條件式,只要條件式返回的布林值為false即可。

2.要複製資料表結構與所有資料

CREATE TABLE [目標表] AS SELECT * FROM [源表];

【注意】:通過這樣的方式複製的資料表,目標表中雖然完整的複製了源表的所有列的型別、大小等資訊,卻唯獨不會包含各列是否是【主鍵】的資訊。

這其實也就是說複製已經基本失敗了。

 

(三)mysql資料庫

mysql是中大型伺服器型關係資料庫。

它的複製資料表的sql語句如下:

1.只複製資料表的結構而不復制源表的資料

CREATE TABLE [目標表] LIKE [源表];

2.要複製資料表結構與所有資料

將在只複製資料表結構的基礎上再多執行一步:

CREATE TABLE [目標表] LIKE [源表];

INSERT INTO [目標表] SELECT * FROM [源表];

【注意】在目前我正在研究的四種資料庫中,只有mysql的表複製sql語句是完美無瑕的。

但:

CREATE TABLE [目標表] LIKE [源表];

只支援mysql5.0以上的版本,多數資料是這樣說的,沒有親自驗證。

 

二、嘗試解決另外三種資料庫的複製資料表後不包括主鍵列資訊的問題

因為複製程式碼執行後,目標資料表並沒有主鍵列的資訊,那就只有後面手動新增上了。

(一)Access

並不能直接修改一個列為主鍵列。

於是根據所查閱到的資料,整理筆記如下:

1.先在資料表中刪除要作為主鍵的列:

alter table [目標表] drop COLUMN [要作為主鍵的列名];

2.再新增這個列,並在新增列的sql程式碼中指定此列為主鍵。

alter table [目標表] add COLUMN [要作為主鍵的列名] 列的資料型別 NOT NULL PRIMARY KEY;

【注意】access只能通過sql語句新增一個列作為主鍵。雖然在access軟體中可以手動指定多個列作為主鍵組。

(二)mssql

mssql可以直接修改一個列或多個列為主鍵列

'alter table [目標表] add CONSTRAINT PK_目標表名稱 PRIMARY KEY NONCLUSTERED (一個或多個要作為主鍵的列名稱);'

當然之前複製資料表時是連同表中資料一起復制的,那麼必須保證要作為主鍵的列中各行中是沒有null值的資料的。

如有必要,應當將此列先指定為not null型的列,sql語句如下:

alter table [目標表] alter column [一個要作為主鍵的列名] 列的資料型別 not null

【注意】雖然mssql可以指定多個列作為主鍵,然而如果這麼做了,若只是複製資料表的結構倒沒有問題,然而一旦要連同資料也一起復制,多數情況下會報完全不相關莫名其妙的錯誤。

(三)sqlite

sqlite的sql語句根本就不能對一個表的中的列的任何屬性進行修改,也不能刪除列。

因此常規方法都已失效。

好在sqlite中有一個相對而言比較簡單的獲取一個數據表所有列完整資訊結構的sql語句:

PRAGMA table_info([源表名]);

通過此sql程式碼將得到一個巢狀列表物件,

通過相關列表轉換操作,就可以還原資料來源表的建立表的sql語句,然後重新建立一個新表,也算作是完成了資料表的結構複製。

如果再要複製資料,則執行 insert into 語句即可從源表向目標表中匯入資料

這算是變通地完成了資料表的複製。

 

三、今天竭盡全力部分完成了通用的同一資料庫中資料表的複製操作的函式

修改後的整個_mdb.py檔案如下:

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

 

import pypyodbc

import pymysql

import pymssql

import sqlite3

import cx_Oracle

 

import os.path

 

import _mty

 

mdbErrString='' #供其它模組使用的全域性變量了,實時儲存了各函式執行時的錯誤資訊

 

#下面是失敗的連線oracle資料庫的測試,已放棄,提示的錯誤是伺服器那邊認為使用者名稱密碼錯誤

def connectoracle():

    con=cx_Oracle.connect("sys/123 as [email protected]/orcl")

    #con=cx_Oracle.connect("adminstrator/ as [email protected]/orcl")

    cur=con.cursor()

    cur.execute('select * from m;')

    data=cur.fetchall()

    print(list(data))

    con.close()

 

def msgbox(info,titletext='孤荷凌寒的DB模組對話方塊QQ578652607',style=0,isShowErrMsg=False):

    return _mty.msgboxGhlh(info,titletext,style,isShowErrMsg)

 

#連線網路資料庫,目前支援mssql,mysql

def conNetdbGhlh(serveraddress,usr,pw,dbname,dbtype='mssql',isShowMsg=False):

    '''

    用於連線網路資料庫,目前支援連線mssql,mysql兩種網路關係型資料庫,

    dbtype可選形參預設值是操作mssql,如果要連線Mysql則通過此可選形參指定:為mysql

    ,此函式返回一個connect資料庫連線物件

    '''

    global mdbErrString

    mdbErrString=''

    try:

        if dbtype=='mssql':

            con=pymssql.connect(serveraddress,usr,pw,dbname,charset='utf8')

            return con

        elif dbtype=='mysql':

            con=pymysql.connect(serveraddress,usr,pw,dbname)

            return con

        else:

            return None

 

    except Exception as e:

        mdbErrString='連線網路資料庫【' + serveraddress + '】【' + dbname + '】時出錯:' + str(e) + '\n此函式由【孤荷凌寒】建立,QQ578652607'

        if isShowMsg==True:

           msgbox(mdbErrString)

        return None

    else:

        pass

    finally:

        pass

 

#連線本地資料庫檔案,目前支援db,mdb,accdb,s3db

def conLocaldbGhlh(dbfilepath,strPass='',isShowMsg=False):

    '''

    連線本地資料庫檔案,目前支援mdb,accdb,以及sqlite資料庫檔案,識別方法是,如果有後綴mdb或accdb,則說明是access資料庫檔案,否則都認為是sqlite資料庫檔案。

    如果連線成功,將返回一個con資料庫連線物件

    '''

    global mdbErrString

    mdbErrString=''

    try:

        strhznm=_mty.getFilehzGhlh(dbfilepath)

        if strhznm.find('mdb')>-1 or strhznm.find('accdb')>-1:

            #---連線access資料庫----

            if strPass=='':

                strname='Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' + dbfilepath

            else:

                strname='Driver={Microsoft Access Driver (*.mdb, *.accdb)};DBQ=' + dbfilepath + ';Pwd=' + strPass

            con=pypyodbc.connect(strname)

            return con

        else:

            #----連線sqlite資料庫-----

            con=sqlite3.connect(dbfilepath)

            return con

 

    except Exception as e:

        mdbErrString='連線網路資料庫檔案【' + dbfilepath + '】時出錯:' + str(e) + '\n此函式由【孤荷凌寒】建立qq號是578652607'

        if isShowMsg==True:

           msgbox(mdbErrString)

        return None

    else:

        pass

    finally:

        pass

 

#刪除資料庫中的表

def delTableGhlh(con,strtablenm,isShowMsg=False):

    '''

    此方法將刪除指定conn中的table,不管table中是否有資料,因此 操作要謹慎

    ,成功返回True 失敗返回False

    '''

    global mdbErrString

    mdbErrString=''

 

    try:

        if strtablenm is not None and strtablenm != '':

            sql = 'DROP TABLE ' + strtablenm

            cur=con.cursor()

            cur.execute(sql)

            con.commit()

            cur.close()

            if isShowMsg==True:

                msgbox('刪除資料庫表[{}]成功!'.format(strtablenm))

            return True

        else:

            if isShowMsg==True:

                msgbox('the [{}] is empty or equal None!'.format(sql))

            return False

    except Exception as e:

        mdbErrString='刪除資料庫中表【' + strtablenm + '】時出錯:' + str(e) + '\n此函式由【孤荷凌寒】建立qq號是578652607'

        if isShowMsg==True:

           msgbox(mdbErrString)

        return False

    else:

        pass

    finally:

        pass

 

#建立一個新表

def newTableGhlh(con,strTableNm,lstnm:'list. 將所有要新建的欄位都放在一個列表中',lsttype,lstlength,dbtype='acc',lstNull=None,isDelExitsTable = False ,isAutoSetIDfieldAutoNumber=True,strSetFieldAutoNumberName='id',isShowMsg= False):

    '''

    傳遞有關表的每個欄位的三大屬性的分別的三個列表,

    並可以指定此表的PRIMARY key 欄位,

    及指定是否自動識別ID欄位為PRIMARY key 欄位,

    如果要建立的表名是否存在,約定是否刪除舊錶

    如果設定為不刪除舊錶,則放棄新建表;

    '''

    global mdbErrString

    mdbErrString=''

    try:

        cur=con.cursor()

        dbtype=dbtype.lower()

        if dbtype=='access':

            dbtype='acc'

    except:

        pass

    #--------------------------------------------------------

    try:

        if strTableNm == "" or strTableNm.lower() == "select" or strTableNm.lower() == "from" or strTableNm.lower() == "where" or strTableNm.lower() == "order" or strTableNm.lower() == "insert" or strTableNm.lower() == "delete" or strTableNm.lower() == "in" or strTableNm.lower() == "with" or strTableNm.find("[") >-1 or strTableNm.find("]") >-1 :

            mdbErrString = "要建立的資料表名為空或為不合法的保留關鍵字,請重新確認資料表名。" + '\n此函式由【孤荷凌寒】建立qq是578652607'

            if isShowMsg == True:

                msgbox(mdbErrString)

            return False

 

        if len(lstnm) != len(lsttype) or len(lsttype) != len(lstlength):

            mdbErrString = "在新建一個數據表時,接收到的四個關於表中欄位屬性的列表引數中元素總數不相同,無法執行。" + '\n此函式由【孤荷凌寒】建立qq號:578652607'

            if isShowMsg == True:

                msgbox(mdbErrString)

           

            return False

 

        #現在先檢查表是否存在,如果存在,根據設定是刪除舊錶然後新建表呢,還是保留舊錶而不新建表

        if isTableExistGhlh(con,strTableNm,isShowMsg)==True:

            #--如果舊錶存在,就看是否要刪除舊錶---

            if isDelExitsTable==True:

                if delTableGhlh(con,strTableNm,isShowMsg)==False:

                    #--舊錶存在,但是卻刪除失敗的情況----

                    mdbErrString = "在新建一個數據表時,因為同名的舊錶已經存在了,但嘗試刪除舊錶失敗,所以無法新增一個表。" + '\n此函式由【孤荷凌寒】建立qq:578652607'

                    if isShowMsg == True:

                        msgbox(mdbErrString)

                    return False

                else:

                    #成功刪除了舊錶,那麼就新增新表,直接順序到後面執行程式碼即可。

                    pass

 

            else:

                #如果舊錶存在,但又指定不刪除舊錶,那麼只好結束 本函式 過程了

                mdbErrString = "在新建一個數據表時,因為同名的舊錶已經存在了,而又指定不能刪除舊錶,所以無法新增一個表。" + '\n此函式由【孤荷凌寒】建立qq是578652607'

                if isShowMsg == True:

                    msgbox(mdbErrString)

                return False

 

        #現在準備開始新增新的表-----

        intC=len(lstnm)

        rals=range(intC)

        strR=""

        strRls=""

        strNm=""

        strLs=""

        intL=0

        strL=""

        strN=""

        for i in rals:

            strNm=lstnm[i]

            strLs =lsttype[i]

            strLs = getStandardFieldTypeGhlh(strLs,dbtype,isShowMsg)

            strLs=' ' + strLs

            #-----------------------

            intL=lstlength[i]

            if intL<=0:

                strL=''

            else:

                strL="(" + str(intL) + ")"

            #----------------

            strN=""

            if lstNull != None:

                try:

                    strN=lstNull[i]

                except:

                    pass

                #---------------

                if strN=="" or strN==None:

                    strN=""

                else:

                    strN=" " + strN

            #----------

            if strLs.find('NULL')>=0:

                #-----如果已經在得到類別時,已經在字串中出現了null關鍵字,此處就不要再處理了

                strN=""

            #---------------

            if dbtype!='mysql':

                #上一條件式是因為,Mysql不允許在sql語句中出現 []括號

                strNm='[' + strNm + ']'

            strRls=strNm + strLs + strL + strN # 此時已經構建了類似於 【name varchar(20)】  這樣的內容了

            #檢查是否主鍵--

            if isAutoSetIDfieldAutoNumber==True:

                #如果強制將欄位名稱為“id”的欄位作為主鍵,則

                if strNm.lower()==strSetFieldAutoNumberName.lower():

                    if strR.find("PRIMARY KEY")<0:

                        #上一條件式是為了避免有多個primary key

                        if strRls.find("PRIMARY KEY")<0:

                            #上一條件式是為了防止在取得可用欄位型別時已新增過Primary key 了

                            strRls=strRls+" PRIMARY KEY"

           

            #現在拼合 strR

            if strR=="":

                strR=strRls

            else:

                strR=strR + "," + strRls

 

        #開始生成sql語句

        strSql='CREATE TABLE ' + strTableNm + '(' + strR + ');'

        #執行--

        cur.execute(strSql)

        con.commit() #提交所作的修改

        #如果沒有出錯,就返回成功

        return True

 

           

           




    except Exception as e:

        mdbErrString='嘗試建立表【' + strTableNm + '】時出錯:' + str(e) + '\n此函式由【孤荷凌寒】建立qq號是578652607'

        if isShowMsg==True:

           msgbox(mdbErrString)

        return False

    else:

        pass

    finally:

        try:

            cur.close()

        except:

            pass

           

#判斷一個表在資料庫中是否存在

def isTableExistGhlh(con,strtablenm,isShowMsg=False):

    '''

    判斷一張表是否在資料庫中存在

    ,需要傳入con資料庫連線物件

    '''

    global mdbErrString

    mdbErrString=''

    try:

        cura=con.cursor()

        return isTableExist2Ghlh(cura,strtablenm,isShowMsg)

       

    except Exception as e:

        mdbErrString='檢查表【' + strtablenm + '】是否存在時出錯(此錯誤一般說明表不存在):' + str(e) + '\n此函式由【孤荷凌寒】建立qq號是578652607'

        if isShowMsg==True:

           msgbox(mdbErrString)

        return False

    else:

        pass

    finally:

        try:

            cura.close

            #pass

        except:

            pass

       

 

#判斷一個表在資料庫中是否存在2

def isTableExist2Ghlh(cur,strtablenm,isShowMsg=False):

    '''

    判斷一張表是否在資料庫中存在

    ,需要傳入資料庫操作指標物件

    '''

    global mdbErrString

    mdbErrString=''

    try:

        strsql='SELECT * FROM ' + strtablenm + ';'

        cur.execute(strsql)

        return True

    except Exception as e:

        mdbErrString='檢查表【' + strtablenm + '】是否存在時出錯(此錯誤一般說明表不存在):' + str(e) + '\n此函式由【孤荷凌寒】建立qq號是578652607'

        if isShowMsg==True:

           msgbox(mdbErrString)

        return False

    else:

        pass

    finally:

        pass

 

#將各種複雜的對資料庫型別的描述,如3,8等數值表示的欄位型別與,windows系統中的system.string,之類的描述,統一修改為資料庫能夠在定義欄位型別時直接使用的描述字串

def getStandardFieldTypeGhlh(strin,dbtype='acc',isShowMsg=False):

    '''

    將各種複雜的對資料庫型別的描述,如3,8等數值表示的欄位型別與,windows系統中的system.string,之類的描述,統一修改為資料庫能夠在定義欄位型別時直接使用的描述字串

    '''

    global mdbErrString

    mdbErrString=''

    strI=""

    try:

        strI=str(strin)

        strI.lower()

        strI=strI.replace('system.','') #windows系統中,以及其它一些語言中對資料型別的描述的字串中,可以包含有system.字首

        strI=strI.replace('.','') #去掉多餘的點

        dbtype=dbtype.lower()

        if dbtype=='access':

            dbtype='acc'

    except:

        pass

    #--------------------------------------------------------

    try:

        if strI=='':

            mdbErrString = "因為傳入的要識別的資料庫的欄位型別為空,因此無法識別,只能識別成【文字型別】【text】。" + '\n此函式由【孤荷凌寒】建立qq:578652607'

            if isShowMsg == True:

                msgbox(mdbErrString)

            if dbtype!='acc' and dbtype!='mysql':

                return 'ntext'

            else:

                return 'text'

        #---正式識別開始---------------------

        if strI in ("int32", "3", "int","int16", "integer", "long","smallint","tinyint","mediumint"):

            if dbtype=='acc':

                return 'long'

            else:

                return "int"  #多數資料庫在這種情況下要額外指定長度

        #----------------------

        if strI=='bigint':

            if dbtype=='acc' or dbtype=='sqlite':

                return 'int'

            else:

                return 'bigint'

        #-----------------

        elif strI in ("memo","longtext","mediumtext"):

            if dbtype=='acc':

                return "memo"

            elif dbtype=='mysql':

                return "longtext"

            else:

                return 'ntext'

        #------------------

        elif strI in ("str","string","8","varchar","char","text","nvarchar","tinytext"):

            if dbtype=='mysql' or dbtype=='acc':

                return "varchar"  #在這種情況下都需要指定長度

            else:

                return "nvarchar"  #在這種情況下都需要指定長度

        #------------------

        elif strI in ("datetime","7"):

            if dbtype=='sqlite':

                return "date"

            else:

                return "datetime"

        #----------------

        elif strI=="date":

            if dbtype!='acc':

                return "date"

            else:

                return "datetime"                

        #-----------------

        elif strI=="time":

            if dbtype!='acc':

                return "time"

            else:

                return "datetime"               

 

        #-----------------

        elif strI in ("single", "4", "real"):

            return "real"

 

        #----------------

        elif strI in ("double", "5", "float"):

            return "float"

        #----------------

        elif strI in ("boolean", "11", "bit","bool"):

            if dbtype=='mssql' or dbtype=='acc':

                return "bit"

            else:

                return 'boolean'

        #-----------------

        elif strI in ("byte[]", "8209", "image", "binary", "ole"):

            #---image為微軟專用的OLE,"Binary" 為 二進位制,在sqlite中使用blob,表示二進位制大資料

            if dbtype=='acc' or dbtype=='mssql':

                return "Image"

            elif dbtype=='sqlite':

                return 'blob'

            else:

                return 'binary'

        #-------這是真正的全精度資料

        elif strI in ("decimal", "14", "money","numeric"):

            if dbtype=='sqlite':

                return 'numeric'

            elif dbtype=='acc':

                return 'money'

            else:

                return 'decimal'

 

        #--------------

        elif strI=="timestamp":

            if dbtype=='acc':

                return 'double'

            else:

                return 'timestamp'

           

        #------自動編號------      

        elif strI in ("auto", "autocount", "autonumber", "autono", "autoincrement","auto_increment"):

            if dbtype=='mysql':

                return 'int NOT NULL auto_increment'

            elif dbtype=='acc':

                return 'counter NOT NULL PRIMARY KEY'

            elif dbtype=='mssql':

                return 'int identity(1,1)'

            else:

                #--sqlite-----------------

                return "integer PRIMARY KEY AUTOINCREMENT NOT NULL"

       

        #--------

        else:

            #其餘情況,全部識別為 text

            if dbtype!='acc' and dbtype!='mysql':

                return 'ntext'

            else:

                return 'text'

 

    except Exception as e:

        mdbErrString='嘗試將各種不同的對資料庫欄位型別的描述轉換為標準欄位型別描述時出錯:' + str(e) + '\n此函式由【孤荷凌寒】建立qq號是578652607'

        if isShowMsg==True:

           msgbox(mdbErrString)

        #------------------------------------------

        if dbtype!='acc' and dbtype!='mysql':

            return 'ntext'

        else:

            return 'text'

    else:

        pass

    finally:

        pass

       

 

#-----複製表的操作----------------

def copyDbTableGhlh(con,strst,strtt,dbtype='acc',strfieldlist='*',strprimarykey='id',strprimarykey2='',isstrprimarykeyautoaccount=False,isstrprimarykey2autoaccount=False,strprimarykeytype='integer',strprimarykey2type='str',iscopydata=False,isShowMsg=False):

    try:

        cur=con.cursor()

        strLs=strtt

        if dbtype!='mysql': #mysql 不支援在sql語句中書寫方括號

            strst='[' + strst + ']'

            strtt='[' + strtt + ']'

 

        strprimarykey=strprimarykey.strip()

        strprimarykey2=strprimarykey2.strip()

        #如果要複製到的目標 表已經存在 ,應當作一定的處理--------

 

        #--------------------------

        strSql='SELECT ' + strfieldlist + ' INTO ' + strtt + ' FROM ' + strst

        if dbtype=='sqlite':

            strSql='CREATE TABLE ' + strtt + ' AS SELECT ' + strfieldlist + ' FROM ' + strst

        if iscopydata==False:

            strSql=strSql + ' WHERE (1=2);'

        else:

            strSql=strSql + ';'

        if dbtype!='mysql':

            #非Mysql的情況下,開始一步執行到位

            cur.execute(strSql) #除Mysql之外的資料庫的複製結果都不能得到完整的資料表資訊,至少 資料表的 主鍵資訊不會複製過來

            #因此下面必須手動再指定主鍵資訊

            #sqlite目前沒有辦法修改主鍵欄位

            if strprimarykey!='':

                if strprimarykey2=='':

                    if dbtype=='acc':

                        #access資料庫第一步先刪除失敗的primary key 欄位,

                        cur.execute('alter table ' + strtt + ' drop COLUMN ' + strprimarykey + ';')

                        #然後新增一個欄位:

                        cur.execute('alter table ' + strtt + ' add COLUMN ' + strprimarykey + ' counter NOT NULL PRIMARY KEY;')

                    if dbtype=='mssql':

                        #mssql的處理也有兩步:

                        #第一步感覺可以取消----

                        #cur.execute('alter table ' + strtt + ' alter column ' + strprimarykey + ' int not null')

                        cur.execute('alter table ' + strtt + ' add CONSTRAINT PK_' + strLs + ' PRIMARY KEY NONCLUSTERED ( ' + strprimarykey + ' )')

                else:

                    #如果有第二個Primarykey

                    pass

        else:

            #mysql的執行比較特殊,分兩步完成

            #第一步複製表的結構,只有mysql是完整複製了資料表的全部資訊,包括主鍵(primary key)的資訊

            cur.execute('CREATE TABLE ' + strtt + ' LIKE ' + strst + ';')

            #第二步是將源表的資料插入到複製後的新表

            if iscopydata==True:

                cur.execute('INSERT INTO ' + strtt + ' SELECT * FROM ' + strst + ';')

 

        con.commit()

        return True

 

    except Exception as e:

        mdbErrString='嘗試在同一資料庫中複製資料表時出錯:' + str(e) + '\n此函式由【孤荷凌寒】建立qq號是578652607'

        if isShowMsg==True:

           msgbox(mdbErrString)

        return False

    else:

        pass

    finally:

        try:

            cur.close()

        except:

            pass

 

#檢查一個活動的當前查詢結果表中是否有指定的記錄值存在,可以支援最多三個條件同時存在的情況

#connectoracle()

 

 

四、然後在Windows10下進行了全面的測試

測試的檔案程式碼如下:

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

 

import pypyodbc

import pymysql

import pymssql

import sqlite3

 

import _mty

import _mdb

 

def msgbox(info,titletext='孤荷凌寒的對話方塊QQ578652607',style=0,isShowErrMsg=False):

    return _mty.msgboxGhlh(info,titletext,style,isShowErrMsg)

 

def conmssql():

    try:

        con=_mdb.conNetdbGhlh("www.lhghroom.cn", "lhghroom", "abc123", "ghlh")

        #pymssql沒有execute()方法,遊標cusor物件有這個方法

        msgbox('mssql')

        cur=con.cursor()

        #cur.execute('select * from pengwei;')

        #data=cur.fetchall()

        #cur.close()

        #建立一張表-----

        #lstNm=['id','nm','sex','yuwen','shuxue','age','birth','memo','img','ispass']

        #lstT=['auto','str','str','double','numeric','int','datetime','memo','ole','bool']

        #lstL=[0,10,2,0,0,0,0,0,0,0]

        #a=_mdb.newTableGhlh(con,'ghlhstable',lstNm,lstT,lstL,'mssql',None,True)

        #msgbox(str(a))

 

        #msgbox('ghlhstable存在嗎?\n' + str(_mdb.isTableExistGhlh(con,'ghlhstable')))

       

        _mdb.copyDbTableGhlh(con,'pengwei','pw1','mssql','*','id','',True,False,'int','',False,True)

        #複製第二張表,要複製資料,但會出現錯誤

        _mdb.copyDbTableGhlh(con,'pengwei','pw2','mssql','*','id','',True,False,'int','',True,True)

        #複製第三張表,要複製資料,但會出現錯誤

        _mdb.copyDbTableGhlh(con,'pengwei','pw3','mssql','*','id','nm',True,False,'int','str',True,True)

 

        #cur.execute('show create table pengwei;') #mssql不支援此語句

        #data=cur.fetchall

        #msgbox(str(list(data)))

       

        msgbox('複製完畢')

 

        msgbox('pw3存在嗎?\n' + str(_mdb.isTableExistGhlh(con,'pw3')))

       

        cur.close()

 

        con.close()

    except Exception as e:

        msgbox('出錯了'+ str(e),'出錯',16)

    finally:

        try:

            cur.close

            con.close

        except:

            pass

        finally:

            pass

 

def conmysql():

    try:

        con=_mdb.conNetdbGhlh("localhost", "root", "abc123", "mysql",'mysql',True)

        #pymysql沒有execute()方法,遊標cusor物件有這個方法

        msgbox('mysql')

        cur=con.cursor()

        #cur.execute("select * from m;")

        #data=cur.fetchall()

        #msgbox(str(data))

        #cur.close()

 

        #建立一張表-----

        #lstNm=['id','nm','sex','yuwen','shuxue','age','birth','memo','img','ispass']

        #lstT=['auto','str','str','double','numeric','int','datetime','memo','ole','bool']

        #lstL=[0,      10,    2,     0,      0,        4,     0,        0,     8,    0]

        #a=_mdb.newTableGhlh(con,'ghlhstable',lstNm,lstT,lstL,'mysql',None,True)

        #msgbox(str(a))

 

        #msgbox('ghlhstable存在嗎?\n' + str(_mdb.isTableExistGhlh(con,'ghlhstable')))

 

        #cur.execute('CREATE TABLE pw2 LIKE m;')

        #cur.execute('INSERT INTO pw2 SELECT * FROM m;')

        #複製第一張表,不復制資料

        _mdb.copyDbTableGhlh(con,'m','pw2','mysql','*')

        #複製第二張表,要複製資料

        _mdb.copyDbTableGhlh(con,'m','pw3','mysql','*','id','',True,False,'integer','str',True,True)

        #con.commit()

       

        cur.close()

        con.close()

    except Exception as e:

        msgbox('出錯了'+ str(e),'出錯',16)

    finally:

        try:

            cur.close

            con.close

        except:

            pass

        finally:

            pass

       

 

def consqlite():

    try:

        stra=r'C:\ProgramData\SQLITE3\slone.s3db'

        con=_mdb.conLocaldbGhlh(stra)

        msgbox('sqlite')

        cur=con.cursor()

 

        #cur.execute('INSERT INTO pengwei VALUES (null,"張三","男",90,90,23,null,"no",null,null);')

        #con.commit()

        #cur.execute("select * from pengwei;")

 

        #data=cur.fetchall()

        #msgbox(str(data))

        #cur.close()

 

        #建立一張表-----

        #lstNm=['id','nm','sex','yuwen','shuxue','age','birth','memo','img','ispass']

        #lstT=['auto','str','str','double','numeric','int','datetime','memo','ole','bool']

        #lstL=[0,      10,    2,     0,      0,        4,     0,        0,     8,    0]

        #a=_mdb.newTableGhlh(con,'ghlhstable',lstNm,lstT,lstL,'sqlite',None,True)

        #msgbox(str(a))

 

        #msgbox('ghlhstable存在嗎?\n' + str(_mdb.isTableExistGhlh(con,'ghlhstable')))

 

        _mdb.copyDbTableGhlh(con,'pengwei','pw2','sqlite',"*",'id','',True,False,'integer','str',False,True)

        #複製第二張表,要複製資料

        _mdb.copyDbTableGhlh(con,'pengwei','pw3','sqlite',"*",'id','',True,False,'integer','str',True,True)

 

        cur.execute("select * from pw3;")

 

        data=cur.fetchall()

        msgbox(str(data))

 

       

        cur.close()

        con.close()

    except Exception as e:

        msgbox('出錯了'+ str(e),'出錯',16)

    finally:

        try:

            cur.close

            con.close

        except:

            pass

        finally:

            pass

 

def conaccess():

    try:

        stra=r'I:\新建資料夾\Database2.mdb'

        #stra=r'I:\新建資料夾\Database1.accdb'

        con=_mdb.conLocaldbGhlh(stra,'',True)

 

        msgbox('accese')

 

        cur=con.cursor()

        #cur.execute("select * from m;")

        #data=cur.fetchall()

        #msgbox(str(data))

        #cur.close()

 

        #建立一張表-----

        #lstNm=['id','nm','sex','yuwen','shuxue','age','birth','memo','img','ispass']

        #lstT=['auto','str','str','double','numeric','int','datetime','memo','ole','bool']

        #lstL=[0,      10,    2,     0,      0,        0,   &nb