在做Oracle数据库导出到TXT文件,又从TXT文件导入数据库的时候,遇到一个问题,其中某些字段的值为null,那么在导入TXT文本的时候,在TXT文本中各个字段之间两个分隔符例如','逗号,两个逗号之间没有内容的即为null,其实这可以通过sqlldr如下的的控制语句解决,但一开始不知道,因此自己写了个python脚本,根据理解对生成的去除了所有空白字符的TXT文件根据分隔符','来做字符分割并替换,功能是当两个分隔符之间的内容是空字符,在python中为 '' 的时候,将其替换为10个空白字符,以便于sqlldr识别出来是null,亲测可行。不过后来这个功能被下面这句话解决了,也就没有在使用python来画蛇添足了。不过这个例子也可以作为一个python的split,join,replace等函数的一个使用例子,就记录下来吧。

TRAILING NULLCOLS --如要导入源文件此列内容为空,在导入到数据库表中,此列内容就是null

这里python脚本还通过调用shell脚本生成了TXT文件,如下

该函数的作用是调用shell脚本,只要将shell脚本的文件名传入即可,dbout.sh见上一篇内容:从Oracle导出数据到TXT文件&从TXT文件导入数据到Oracle

def call_shell2dbout():
    shell_find = os.path.join(os.getcwd(), 'dbout.sh')
    cmd = 'sh ' + shell_find
    logging.debug('calllling shell to dbout... cmd = %s' %(cmd))
    re = os.system(cmd)
    if 0 == re:
        logging.debug('success to calling shell to dbout')
    else:
        logging.debug('shell calling failed!')
        return None

    logging.debug('dbout end!')

注意,python脚本中有中文的时候,第一行追加utf8格式,如下

#!/bin/python # -*- coding: utf-8 -*

完整的python脚本如下:

功能是打开TXT文件读取内容,并使用split分割,最后将符合要求的内容重新写入另一个文件

#!/bin/python # -*- coding: utf-8 -*

import os
import sys
import logging
LOG_FORMAT = "%(asctime)s %(name)s %(levelname)s %(pathname)s %(message)s "#配置输出日志格式
DATE_FORMAT = '%Y-%m-%d  %H:%M:%S %a ' #配置输出时间的格式,注意月份和天数不要搞乱了
LOG_PATH = None #os.path.join(os.getcwd(),'debugging.log')
logging.basicConfig(level=logging.DEBUG,
                    format=LOG_FORMAT,
                    datefmt = DATE_FORMAT ,
                    filename=LOG_PATH #有了filename参数就不会直接输出显示到控制台,而是直接写入文件
                    )
#分割字符
def split_txt():
    rfile_path = os.path.join(os.getcwd(), 'stu_20190810.txt')
    wfile_path = os.path.join(os.getcwd(), 'stu_20190810_s.txt')
    rfile = open(rfile_path, 'r')
    wfile = open(wfile_path, 'w')
    contents = rfile.readlines()
    #wait to write strings
    str_write = []
    for str_val in contents:
        #string
        str_val = str_val.replace('\n', '')
        #list
        lst_val = str_val.split(',')
        #length of list
        lst_spl_len = len(lst_val)
        logging.debug('after split: val_spl = ' +str(lst_val))

        #special proc
        for i in range(lst_spl_len):
            if lst_val[i] == '' or lst_val[i] == '\n':
                logging.debug("lst_val[%d] = '' " %(i))
                lst_val[i] = ' ' * 10
        #append
        seg = ','
        str_write.append(seg.join(lst_val))
        logging.debug('after fix :val_spl = ' + seg.join( lst_val))
        
    for val in str_write:
        wfile.write(val+'\n')
    
    rfile.close()
    wfile.close()
#调用shell脚本dbout.sh
def call_shell2dbout():
    shell_find = os.path.join(os.getcwd(), 'dbout.sh')
    cmd = 'sh ' + shell_find
    logging.debug('calllling shell to dbout... cmd = %s' %(cmd))
    re = os.system(cmd)
    if 0 == re:
        logging.debug('success to calling shell to dbout')
    else:
        logging.debug('shell calling failed!')
        return None

    logging.debug('dbout end!')


if __name__ == '__main__':
    call_shell2dbout()
    split_txt()

测试结果:

python 空格转逗号数组 python逗号转换为空格_python

生成的文本,如行尾内容为null,则在行位添加了10和空白字符,中间的字段为null,在该字段添加了10个空白字符。

readlines读取文件返回字符串数组,单个成员为字符串

append向列表尾部添加一个元素,可以使任何类型,无需统一类型。