在做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()
测试结果:
生成的文本,如行尾内容为null,则在行位添加了10和空白字符,中间的字段为null,在该字段添加了10个空白字符。
readlines读取文件返回字符串数组,单个成员为字符串
append向列表尾部添加一个元素,可以使任何类型,无需统一类型。