2017-09-08 5 views
0

나는 column_list.csv에있는 ALL_TAB_COLUMNS (TABLE_NAMECOLUMN_NAME 열만 추출)과 일치하는 파일을 .SQL 개 묶어 놓은 폴더가 있습니다.dic 및리스트를 반복하는 방법

내 목표는 같은 출력을 발생시키는 각 리포트에 대해 사용되는 테이블/컬럼의 관계를 가지고있다 :
sql_file_name.sql | table_name | column_name

내가 변수 제 중첩 루프 초에서 움직일 때에서 '있어 보인다 '도달 Python (2.7.13) 신규로 취급 :

import os 
import csv 

path = "./search_files" 
folder = os.listdir(path) 

search_dict = csv.DictReader(open("column_list.csv")) 

for files in folder: 
    files = os.path.join(path, files) 
    file = open(files, "r") 
    sql = file.readlines() 

    sql = [x.strip() for x in sql] # Remove \n 

    hit_count = 0 

    for i in sql: 
     i = i.upper() # Make SQL code UPPERCASE 
     print str(hit_count) + ": " + i # i has values here 
     hit_count = hit_count + 1 

     for row in search_dict: 
      print str(hit_count) + ": " + i # i is blank here 
      hit_count = hit_count + 1 

      if row['TABLE_NAME'] in i or row['COLUMN_NAME'] in i: 
       print row['TABLE_NAME'] + " | " + row['COLUMN_NAME'] 
+0

궁금해서 출력물을 붙여 넣을 수 있습니까? 나는 당신이 당신의 SQL 파일에 몇 가지 빈 줄을 의심 ... – kaza

+1

물론 할 수 있습니다. '455 : CASE LSZ55EXCC2 = '05'THEN '07'ELSE LSZ55EXCC2의 END, 1456 '' 1,457 : IMLITM, 1,458 : LSZ55TABC, 1,459 : LSZ55COMP이 첫 번째 인쇄 출력 추출물 인 , 1,460 : LSZ55AENT, 1,461 : LSZ55MENT, 1,463'이것은 secound 하나 인 : '6469 : 6470 : 6471 : 6472 : 6473 : 6474' 마지막 인쇄물이 출력되지 않습니다. – Fdiang

+0

잠시만 기다려주세요. 가능성이 있습니다. 당신의'search_dict'는 비어 있습니다! 당신의 산출물의 모습. 그러므로'column_list.csv'가 적절한 지 확인하십시오. 'column_list.csv'를 cat하고 질문을 편집하여 처음 몇 줄을 보여줄 수 있습니까? – kaza

답변

1

문제는 search_dict이 반복자 점이다, 당신은 그것을 여러 번 반복하려는. 그건 작동하지 않습니다. 처음으로 입력 파일의 끝에 도달하면 이터레이터는 영원히 비어있게됩니다.

해결할 수있는 몇 가지 방법이 있습니다. 가장 쉬운 목록에 반복자의 값을 덤프 아마이 방법에

search_dict = list(csv.DictReader(open("column_list.csv"))) 

유일한 단점은 CSV 파일이 큰 경우가 많은 메모리를 사용할 수 있다는 것입니다.

또는 반복기 프로토콜을 사용하여 비트를 "속이십시오". 일반적으로 StopIteration 예외를 발생시킨 반복자는 계속해서 그렇게해야합니다. 그러나 파일은 당신이 조금씩 속일 수있는 반복자입니다. seek 파일을 다시 시작 부분으로 가져 가면 해당 내용을 다시 반복 할 수 있습니다. 이 은 되감기 한 파일에서 입력을받는 다른 반복자를 계속 반복 할 수 있습니다. 이것이 항상 효과가 있다는 보장은 없습니다. csv.readercsv.DictReader을 처리하지만 pure Python으로 작성된 generator 함수에서는 작동하지 않습니다.

search_file = open("column_list.csv")  # keep a reference to this file for later 
search_dict = csv.DictReader(search_file) 

for files in folder: 
    #... 
    for i in sql: 
     #... 

     search_file.seek(0)     # ensure we're at the start of the file 
     for row in search_dict: 
      #... 

또 다른 방법은 단순히 파일 당신이 내부 루프를 시작할 때마다 다시하는 것입니다 :

그래서 여기에 당신이 당신의 코드를 적응할 수있는 하나의 방법입니다.

루핑 문제와 관련없는 또 다른 제안 : 파일 닫기에 대해 좀 더주의해야합니다. with 문을 사용하면 Python에서 매우 쉽게 수행 할 수 있습니다. var = open(filename)과 같은 것을 사용하는 대신 with open(filename) as var:을 사용하고 그 파일을 사용하는 모든 코드를 들여 쓰게하십시오. 들여 쓰기 된 블록을 종료하면 파일이 자동으로 닫힙니다 (예외로 인해 종료하더라도). 내 예는 위의 파일을 여는 현재 스타일을 유지,하지만 난 내 자신의 코드를 작성하는 경우, 내가 쓸 것 :

with open("column_list.csv") as search_file: # the whole code is indented under this block 
    search_dict = csv.DictReader(search_file) 

    for files in folder: # files is a really misleading variable name 
     files = os.path.join(path, files) 
     with open(files, "r") as file: 
      sql = file.readlines() # only a single line needs to be indented extra this time 

     #... 

그리고 마지막으로 :

with open("column_list.csv") as search_file: 
    search_dict = list(csv.DictReader(search file)) 

# rest of the code is not indented extra 

을 또는 seek(0) 버전 제안 : 더 나은 변수 이름을 사용하십시오. 이 문제로 인해 혼란 스러웠던 부분은 search_dict이었습니다. 이 이름은 하나의 사전을 포함해야하는 것처럼 들리게합니다. 그러나 그것은 실제로 코드에 있던 것이 아닙니다 (실제로는 반복자로 사용했던 csv.DictReader 인스턴스였습니다). 마찬가지로 files 변수 (가장 바깥 쪽의 for 루프에 의해 생성됨)도 오해의 소지가 있습니다.그것은 하나의 파일명이 아니라 여러개의 파일들 (복수 명칭이 제시하는)이 아닌 하나의 파일명을 가지고 있습니다.

+0

내 검색 결과가'search_dict'가 정상 'dict'. 하나는 당신이''(0)을 찾을 필요없이 여러 번 반복 할 수있다. – kaza