300 개가 넘는 파일을 생성하는 Python 프로그램이 있으며이를 bcp
을 사용하여 MSSQL으로 옮깁니다. 동시에 약 21 개의 파일이 생성되고 동시에 bcp가 실행되므로 높은 수준의 동시성이 있습니다. 여기서, 프로그램의 중요한 부분이다100 개가 넘는 작업에서 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
:
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 %의 오류를 고쳤지 만, 오늘날 나는 거대한 직업으로 인해 나를 돌아 오게되었다.
것들 내가 오류를 복구하려고 :
- 다시 실행 같은 bcp 명령 전에 1 시간 수면을 추가 - 입력 파일의 복사본을 만들기
- 실패 다시 실행 bcp 명령을 - 실패 ,536 : 명령 줄에서 수동으로 BCP 명령을 실행 는
- 항상
더 자세한 코드 발췌를 작동
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