【问题标题】:csv to txt python conversion script leaves file with 0 bytescsv到txt python转换脚本留下0字节的文件
【发布时间】:2019-07-04 20:17:15
【问题描述】:

我有一个 SSIS 循环包,它多次调用 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 包:

来自 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)

【问题讨论】:

  • 我建议您更新以使用 with open(......) as ... 而不是单独的 open()close()。如果出现问题,这将确保文件被关闭。
  • 谢谢马丁。我确实先尝试过。结果相同。我在主要问题中添加了该代码。也许它会为你打开一些东西。我很感激。
  • 我假设您在输出中看到write。您可以在退出前显示文件大小(参见os.path.getsize()
  • 我看到在标准输出中写入。这是发现问题的第一个迹象。
  • 尝试将时间戳附加到输出文件名

标签: python csv ssis


【解决方案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)

【讨论】:

  • 不报错,有没有办法等5秒再试?
  • 是的,可以使用WaitForSingleObject()
  • 这是完美的!非常感谢马丁!
猜你喜欢
  • 2017-01-31
  • 2021-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-11
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多