我有一个Python程序,可生成300多个文件,并使用bcp
将它们移动到MSSQL。由于大约生成了21个文件并且同时进行了bcp,因此存在高级别的并发性。这是该计划的关键部分:
cmd = ['bcp', self.bcptbl, 'IN', outfile, '-f', 'bcpfmt.fmt', '-m1', '-U', uid, '-S', self.srv, '-P', pwd]
subprocess.check_output(cmd)
一次三个批处理线程,每个7个子线程,所以21个并发进程。随机文件bcp
失败并显示错误:
[Microsoft][SQL Server Native Client 11.0]Unable to open BCP host data-file
该错误可能与我在调用BCP之前创建文件的方式有关:
with open(outfile, 'a') as outf:
proc = Popen('ext_prog.exe', stdin=PIPE, stdout=outf, stderr=PIPE)
_, err = proc.communicate(input='\n'.join(patterns).encode('latin1'))
有些东西告诉我外部程序没有释放文件句柄,即使文件打开和关闭似乎是我处理的。
这不是典型的错误,因为权限,文件夹,路径等都已正确设置,因为它在失败之前成功复制了80~150个文件。
上述代码中的BCP调用经常失败,直到我在bcp调用之前插入以下检查:
@staticmethod
def wait_file_is_ready(outfile):
try:
with open(outfile, 'r'):
print("File {} is ready for reading".format(outfile))
except BaseException as e:
print("File {} is not ready: {}".format(outfile, e))
我的理由是Windows不会将文件标记为关闭,因此打开和关闭它会有所帮助。这修复了99%的错误,但是我今天得到的大量工作又回来困扰着我。
我试图从错误中恢复的东西:
更详细的代码摘录:
MAX_THREADS = 7
def start_batch(self):
ts = []
self.patternq = queue.Queue()
self.bcptbl = '"tempdb.dbo.outtbl_{}"'.format(randint(0,1E15))
for thread_no in range(MAX_THREADS):
tname = "thread_{:02}_of_{}".format(thread_no, MAX_THREADS)
t = Thread(name=tname, target=self.load, args=(thread_no,))
t.start()
ts.append(t)
for t in ts:
t.join()
def load(self, thread_no):
outfile = "d:\\tmp\\outfile_{}_{:02}.temp".format(
randint(0,1E15), thread_no)
try:
os.unlink(outfile)
except FileNotFoundError:
pass
while True:
try:
patterns = self.patternq.get_nowait()
except queue.Empty:
break
with open(outfile, 'a') as outf:
proc = Popen('ext_prog.exe', stdin=PIPE, stdout=outf, stderr=PIPE)
_, err = proc.communicate(input='\n'.join(patterns).encode('latin1'))
cmd = ['bcp', self.bcptbl, 'IN', outfile, '-f', 'bcpfmt.fmt', '-m1', '-U', uid, '-S', self.srv, '-P', pwd]
try:
subprocess.check_output(cmd)
except subprocess.CalledProcessError as e:
# OK, it failed because "Unable to open BCP host data-file"
# How can I recover from it?
raise
答案 0 :(得分:0)
我通过使用ODBC来缓慢而谨慎地插入记录来解决这个问题。这在3次中有2次奏效。这是我在第三次迭代时得到的错误:
os.unlink(OUTFILE) PermissionError:[WinError 32]进程无法访问该文件,因为它正由另一个进程使用:'d:\ tmp \ outfile_678410328373703.temp_03'
错误的可行解释: Seems to be an issue long standing and a bug inherent with Windows 7
中找到了这个似乎是一个长期存在的问题,也是Windows 7固有的错误。
MS没有承认此错误的“官方”声明因此不太可能发布修补程序或修补程序。上面的线程中的一些用户提供了“修复”但是它们在工作流生产率方面太耗时且效率低。这不应该是购买新操作系统时必须处理的问题......