csv到txt python转换脚本将文件保留为0字节

时间:2019-07-04 20:17:15

标签: python csv ssis

我有一个SSIS Loop包,它多次调用python脚本。

意图:

有一个csv文件文件夹。我需要将它们转换为以竖线分隔的文本文件。一些文件中有错误的行。 python脚本可将csv文件转换为管道文件,同时删除不良记录。

python代码:

import csv
import sys

if len(sys.argv) != 4:
    print(sys.argv)
    sys.exit("usage: python csvtopipe.py <<SOURCE.csv>> <<TARGET.txt>>  <<number of columns>>")

source = sys.argv[1]
target = sys.argv[2]
colcount = sys.argv[3]

file_comma =  open(source, "r", encoding="unicode_escape")
reader_comma = csv.reader(file_comma, delimiter=',')
file_pipe = open(target, 'w', encoding="utf-8")
writer_pipe = csv.writer(file_pipe, delimiter='|', lineterminator='\n')
for row in reader_comma:
    if len(row) == int(colcount):
        print("write this..")
        writer_pipe.writerow(row)
file_pipe.close()
file_comma.close()

SSIS程序包:

enter image description here enter image description here

来自SSIS的python调用:

python csvtopipe.py <<SOURCE.csv>> <<TARGET.txt>>  <<number of columns>>

问题。

该循环正常工作,但是当单个调用结束时,文件将重新写入0字节。我不知道这是SSIS问题还是python问题。

谢谢!

更新1

这是代码的原始版本。相同的结果:

import csv
import sys


if len(sys.argv) != 4:
    print(sys.argv)
    sys.exit("usage: python csvtopipe.py <<SOURCE.csv>> <<TARGET.txt>>  <<number of columns>>")

source = sys.argv[1]
target = sys.argv[2]
colcount = sys.argv[3]

with open(source, "r", encoding="unicode_escape") as file_comma:
    reader_comma = csv.reader(file_comma, delimiter=',')
    with open(target, 'w', encoding="utf-8") as file_pipe:
        writer_pipe = csv.writer(file_pipe, delimiter='|', lineterminator='\n')
        for row in reader_comma:
            if len(row) == int(colcount):
                print("write")
                writer_pipe.writerow(row)

1 个答案:

答案 0 :(得分:1)

首先,我将切换为使用with open()...,而不是分别使用open()close()函数。这将有助于确保在出现问题时自动关闭文件。

由于脚本被多次调用,我将在输出文件名中添加一个时间戳。这将有助于确保每次运行该文件时,都会生成一个不同的文件。

最后,您可以添加一个测试以确保仅同时执行脚本的一个副本。对于基于Windows的应用程序,可以使用Windows Mutex完成。在Linux上,可以使用文件锁。有时将这种方法称为singleton pattern

import win32event
import win32api
from winerror import ERROR_ALREADY_EXISTS
from datetime import datetime
import csv
import sys
import os
import time

if len(sys.argv) != 4:
    print(sys.argv)
    sys.exit("usage: python csvtopipe.py <<SOURCE.csv>> <<TARGET.txt>>  <<number of columns>>")

# Wait up to 30 seconds for another copy of the script to stop running
windows_mutex = win32event.CreateMutex(None, False, 'CSV2PIPE')
win32event.WaitForSingleObject(windows_mutex, 30000)

source = sys.argv[1]
target = sys.argv[2]
colcount = sys.argv[3]

# Add a filestamp
path, ext = os.path.splitext(target)
timestamp = datetime.now().strftime("%Y_%m_%d %H%M_%S")
target = f'{path}_{timestamp}{ext}'

with open(source, "r", encoding="unicode_escape") as file_comma, \
    open(target, 'w', encoding="utf-8") as file_pipe:

    reader_comma = csv.reader(file_comma, delimiter=',')
    writer_pipe = csv.writer(file_pipe, delimiter='|', lineterminator='\n')

    for row in reader_comma:
        if len(row) == int(colcount):
            print("write this..")
            writer_pipe.writerow(row)