2016-05-25 3 views
0

Ich verwende eine Schleife, um den Inhalt von fetchone(), jedes Mal, wenn Code fetchone() liest der Cursor bewegt sich in die nächste Zeile. Ich verstehe, dass ich vorsichtig sein muss. Ich bin mit dem Beispiel hier https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-fetchone.html dies funktioniert, wenn ich mehr als eine Zeile haben, aber wenn es eine einzige Zeile bekomme ich einen FehlerLesen erste Zeile in Schleife mit sqlite Fetchone()

for k, v in cur.fetchone().items(): 
AttributeError: 'NoneType' object has no attribute 'items' 

Die beiden relevanten Funktionen

def dict_factory(cursor, row): 
    d = {} 
    for idx, col in enumerate(cursor.description): 
     d[col[0]] = row[idx] 
    return d 

def open_sql(sql_folder, sql_name, sql_table): 
    # databases are located at /work/jmjohnso1/db_project 
    path_name = os.path.join(sql_folder,sql_name).strip() 
    con = lite.connect(path_name) 
    con.row_factory = dict_factory 
    cur = con.cursor() 
    cur.execute('SELECT * FROM ' + sql_table) 

    dict_contents = defaultdict(list) 

    for row in cur: 
     for k, v in cur.fetchone().items(): 
      dict_contents[k].append(v) 

    con.close() 
    print(dict_contents) 
    return dict_contents 

Falls Sie wollen der gesamte Code:

# python3.5 
# pymongo version 3.2.2 
# MongoDB shell version: 3.0.11 

import os 
import pymongo 
from pymongo import MongoClient 
import sqlite3 as lite 
import pyewf 
import hashlib 
from itertools import chain 
from collections import defaultdict 
import pprint 

def list_sql_db(folder): 
    # need a list for multiprocessing so I made a file. 
    file_name = os.path.join(folder, 'sql_db') 
    if not os.path.isfile(file_name): 
     with open (file_name, 'w') as line: 
      for (dirpath, dirs, files) in os.walk(folder): 
       for name in files: 
        line.write(name + '\n') 
    return file_name  

def dict_factory(cursor, row): 
    d = {} 
    for idx, col in enumerate(cursor.description): 
     d[col[0]] = row[idx] 
    return d 

def open_sql(sql_folder, sql_name, sql_table): 
    # databases are located at /work/jmjohnso1/db_project 
    path_name = os.path.join(sql_folder,sql_name).strip() 
    con = lite.connect(path_name) 
    con.row_factory = dict_factory 
    cur = con.cursor() 
    cur.execute('SELECT * FROM ' + sql_table) 

    dict_contents = defaultdict(list) 

    for row in cur: 
     for k, v in cur.fetchone().items(): 
      dict_contents[k].append(v) 

    con.close() 
    print(dict_contents) 
    return dict_contents 

def insert_tsk_mongo(sql_folder, sql_name, sql_table): 
    client = MongoClient() # connect to mongodb 
    db = client.nus # make or use a db called nus 
    contents = open_sql(sql_folder, sql_name, sql_table) 
    collection = sql_name.strip().replace('-','_') # because mongo will write but not read a collection with - 

    # document_id = db[collection].insert({ # sql_name is the hard drive name 
     # sql_table: 
      # contents   
    # }) 

############################################################################### 

sql_folder = '/work/jmjohnso1/db_project'  
# sql_tables = ['tsk_fs_info', 'tsk_image_info', 
       # 'tsk_db_info ', 'tsk_image_names', 
       # 'tsk_file_layout', 'tsk_objects', 
       # 'tsk_files', 'tsk_vs_info', 'tsk_vs_parts'] 

sql_tables = ['tsk_fs_info']    

sql_folder_name = list_sql_db(sql_folder) 

with open (sql_folder_name, 'r') as read: 
    sql_names = read.readlines() 

for sql_name in sql_names: 
    for sql_table in sql_tables: 
     insert_tsk_mongo(sql_folder, sql_name, sql_table) 
    break  

Antwort

2

Sie holen Reihen zweimal, einmal mit der for row in cur: Schleife, dann in der Schleife mit cur.fetchone(). In der letzten Zeile haben Sie keine Zeilen mehr zum Abrufen mehr, daher wird None zurückgegeben.

Es gibt keine Notwendigkeitcur.fetchone() zu verwenden, wenn Sie bereits den Cursor durchlaufen. Lassen Sie einfach den cur.fetchone() Aufruf fallen und verwenden Sie die Zeile, die Sie bereits mit for:

for row in cur: 
    for k, v in row.items(): 
     dict_contents[k].append(v) 
abgerufen haben