天天看點

轉換csv檔案為插入的sql腳本【本地轉換實作方案】

作者:趣味樂高

轉換csv檔案為插入的sql腳本【本地轉換實作方案】

背景:

公司資料從其中一台伺服器上的資料庫中導出成csv格式,有時為了友善進行本地資料的調試,需要将這些資料進行插入到一個測試庫中,一條條去轉換為insert語句,耗時也耗人力成本,那能不能針對導出的檔案進行轉換,生成高效的insert的sql腳本呢?

解決方案:

1.檢視導出的csv檔案内容格式

轉換csv檔案為插入的sql腳本【本地轉換實作方案】

前面是一個資料庫名字,後面跟着一個查詢語句,接下來是表的資料

我們發現,如果沒有資料的,會直接線上無資料,那樣,這個表就不需要生成insert腳本了

然後有多條資料的,如果一條條的插入,那樣會造成頻繁的資料連接配接通路,插入效率低下,需要進行優化,一個庫表就隻生成一條插入語句就好了,當然這個是針對MYSQL的插入方式的優化,其他資料庫需要再進行定制化。

2.進行csv檔案内容的解析

def TransFile(self):
    """
    檔案解析
    :return:
    """
    if not os.path.exists(self.CSVFile):
        return None
    sqlrow = ''
    tbcols = ''
    colstart = 0
    with open(self.CSVFile, 'r', encoding='gbk') as csvf:
        rowreader = csv.reader(csvf)
        for row in rowreader:
            if len(row) > 3:
                if row[0] == '' and row[1] == '' and row[2] == '':
                    # 空行直接跳過
                    continue
            for item in row:
                # if item == '':
                #     break
                if len(str(item).split(':select')) == 2:
                    if len(sqlrow) > 1:
                        sqlrow = sqlrow[:-2] + ';\n'
                    self.saveTbSql(sqlrow)
                    tbstart = True
                    colstart = 1
                    tbcols = ''
                    tbname = str(item).split('from')[1].split('where')[0].strip(' ')
                    print(tbname)
                    sqlrow = 'insert into `{}`'.format(tbname)
                    if tbname.find('cq_user_title') > 0:
                        pass
                    break
                if str(item) == '無資料':
                    #如果沒有資料的則不生成insert sql腳本
                    sqlrow = ''
                    tbstart = False
                    break
                if tbcols == '':
                    tbcols = "'{}'".format(item)
                else:
                    tbcols = "{},'{}'".format(tbcols, item)
            if tbstart == True:
                #加入insert into的表頭
                if colstart >= 2:
                    tbstart = False
                    sqlrow = '{}({})values\n'.format(sqlrow, tbcols.replace("'", "`"))
                    tbcols = ''
                colstart +=1
            else:
                sqlrow = '{}({}),\n'.format(sqlrow, tbcols)
                tbcols = ''
        #儲存最後的一個表的資料
        if len(sqlrow) > 1:
            sqlrow = sqlrow[:-2] + ';\n'
        self.saveTbSql(sqlrow)
        csvf.close()
        self.TranssaveTbSql()
    return self.WebbasePath, self.WebDir, self.SaveFile           

3.進行insert的sql檔案的儲存

def saveTbSql(self,rowinfo):
    """
    儲存腳本
    :param rowinfo:
    :return:
    """
    if rowinfo == '();\n':
        return
    transrow = str(rowinfo).replace(',;', ';').replace(',()', '').replace('(),\n','')
    if transrow == '':
        return
    with open('{}{}'.format(self.WebbasePath, self.SaveFile), 'a+', encoding='gbk') as sqlf:
        sqlf.write(transrow)
        sqlf.close()           

4.進行多條insert腳本的合并,生成高效的插入腳本

def TranssaveTbSql(self):
    """
    儲存腳本
    :param rowinfo:
    :return:
    """
    with open('{}{}'.format(self.WebbasePath, self.SaveFile), 'r', encoding='gbk') as sqlf:
        rowinfo = sqlf.readlines()
        with open('{}{}tmp'.format(self.WebbasePath, self.SaveFile), 'a+', encoding='gbk') as sqlftmp:
            index = -1
            rowcount = len(rowinfo)
            for row in rowinfo:
                index +=1
                # if index == 0:
                #     #第一行的空的去掉
                #     continue
                transrow = str(row).replace(';*****', ';').replace(',()', '').replace(",'','',''", '').replace(",``", '')
                transrow = transrow.replace(",'')", '==*==').replace('==*==', ')').\
                    replace(",'')", '==*==').replace('==*==', ')')

                if rowcount - 1 == index:
                    transrow = transrow.replace('),', ');')
                sqlftmp.write(transrow)
            sqlftmp.close()
        sqlf.close()
    os.remove('{}{}'.format(self.WebbasePath, self.SaveFile))
    os.renames('{}{}tmp'.format(self.WebbasePath, self.SaveFile), '{}{}'.format(self.WebbasePath, self.SaveFile))
           

5.制作本地用戶端的錄入界面

轉換csv檔案為插入的sql腳本【本地轉換實作方案】

打開生成的sql檔案,就會看到類似這樣的結果了:

轉換csv檔案為插入的sql腳本【本地轉換實作方案】

在本地會有這樣的sql檔案生成

轉換csv檔案為插入的sql腳本【本地轉換實作方案】

這個是每次轉換都會生成一個sql檔案,可以直接拿着這個生成好的sql腳本進行刷庫了。

結語:

好的這次的分享就到這,感謝閱讀!

繼續閱讀