Reputation: 571
I am using a loop to get the contents of fetchone(), every time code reads fetchone() the cursor moves to the next row. I understand that I need to be careful. I am using the example found here https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursor-fetchone.html this works when I have more then one row but when there is a single row I get an error
for k, v in cur.fetchone().items():
AttributeError: 'NoneType' object has no attribute 'items'
The two relevant functions
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
In case you want the entire 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
Upvotes: 1
Views: 2470
Reputation: 1123840
You are fetching rows twice, once with the for row in cur:
loop, then in the loop with cur.fetchone()
. At the last row, you have run out of rows to fetch, so None
is returned.
There is no need to use cur.fetchone()
when you are already looping over the cursor. Just drop the cur.fetchone()
call and use the row you already fetched with for
:
for row in cur:
for k, v in row.items():
dict_contents[k].append(v)
Upvotes: 4