2016-11-29 3 views
0

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

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 %의 오류를 고쳤지 만, 오늘날 나는 거대한 직업으로 인해 나를 돌아 오게되었다.

것들 내가 오류를 복구하려고 :

  • 다시 실행 같은 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 

답변

0

ODBC를 사용하여 천천히 그리고 신중하게 레코드를 삽입하여 문제를 해결했습니다. 그것은 3 번 중 2 번을했습니다.

os.unlink (OUTFILE) PermissionError : [WinError 32] 다른 프로세스에 의해 사용 중이므로 프로세스에서 파일에 액세스 할 수있다 : 'D : \ TMP \ outfile_678410328373703 여기서 I는 세 번째 반복에있어 오류이다. temp_03 '

그리고 오류에 대한 가능한 설명 : Seems to be an issue long standing and a bug inherent with Windows 7

Found this in MS forums

Seems to be an issue long standing and a bug inherent with Windows 7.

There has been no "official" statement from MS acknowledging this bug hence a patch or fix release is unlikely. Some users in the thread above have offered "fixes" but they are way too time consuming and inefficient in regards to workflow productivity. This shouldn't be an issue one has to deal with when purchasing a new OS ...

관련 문제