从Access数据库读取大量数据
Reading large amount of data from Access database
正在寻求有关如何解决我的特定问题的建议(MemoryError
由于在一个变量中存储了太多信息),以及有关解决问题的不同方法的一般性建议。
我有一个 Access 1997 数据库,我正试图从中提取数据。由于我安装了 Access 2013,我无法在不下载 Access 2003 的情况下打开数据库。没问题——我可以使用 pyodbc
和 Jet 使用 python.
进行提取
我建立了到数据库的 pyodbc
游标连接,并编写此函数以首先查询所有 table 名称,然后是与这些 table 关联的所有列:
def get_schema(cursor):
"""
:param cursor: Cursor object to database
:return: Dictionary with table name as key and list of columns as value
"""
db_schema = dict()
tbls = cursor.tables().fetchall()
for tbl in tbls:
if tbl not in db_schema:
db_schema[tbl] = list()
column_names = list()
for col in cursor.columns(table=tbl):
column_names.append(col[3])
db_schema[tbl].append(tuple(column_names))
return db_schema
我得到的变量看起来像这样:
{'Table 1': [('Column 1-1', 'Column 1-2', 'Column 1-3')],
'Table 2': [('Column 2-1', 'Column 2-2')]}
然后我将该模式变量传递给另一个函数,以将每个 table 中的数据转储到元组列表中:
def get_table_data(cursor, schema):
for tbl, cols in schema.items():
sql = "SELECT * from %s" % tbl # Dump data
cursor.execute(sql)
col_data = cursor.fetchall()
for row in col_data:
cols.append(row)
return schema
但是,当我尝试读取返回的变量时,我得到以下信息:
>>> schema2 = get_table_data(cursor, schema)
>>> schema2
Traceback (most recent call last):
File "<input>", line 1, in <module>
MemoryError
TL;DR:当数据太大而无法读取时,有没有办法开始将数据存储在另一个变量中?或者增加内存分配的方法?最后,我想将其转储到 csv 文件或类似的文件中——有没有更直接的方法来解决这个问题?
您可能希望能够将数据流出数据库,而不是一次性加载所有数据。这样您就可以直接将数据写回,而不会一次将太多数据加载到内存中。
最好的方法是使用 generators。
因此,与其像现在这样修改模式变量,不如在从数据库表中读取时产生各种行:
def get_single_table_data(cursor, tbl):
'''
Generator to get all data from one table.
Does this one row at a time, so we don't load
too much data in at once
'''
sql = "SELECT * from %s" % tbl
cursor.execute(sql)
while True:
row = cursor.fetchone()
if row is None:
break
yield row
def print_all_table_data(cursor, schema):
for tbl, cols in schema.items():
print(cols)
rows = get_single_table_data(cursor, tbl)
for row in rows:
print(row)
这显然只是一个示例,但它(理论上)会打印出所有表中的每一行 - 内存中一次不会有超过一行的数据。
正在寻求有关如何解决我的特定问题的建议(MemoryError
由于在一个变量中存储了太多信息),以及有关解决问题的不同方法的一般性建议。
我有一个 Access 1997 数据库,我正试图从中提取数据。由于我安装了 Access 2013,我无法在不下载 Access 2003 的情况下打开数据库。没问题——我可以使用 pyodbc
和 Jet 使用 python.
我建立了到数据库的 pyodbc
游标连接,并编写此函数以首先查询所有 table 名称,然后是与这些 table 关联的所有列:
def get_schema(cursor):
"""
:param cursor: Cursor object to database
:return: Dictionary with table name as key and list of columns as value
"""
db_schema = dict()
tbls = cursor.tables().fetchall()
for tbl in tbls:
if tbl not in db_schema:
db_schema[tbl] = list()
column_names = list()
for col in cursor.columns(table=tbl):
column_names.append(col[3])
db_schema[tbl].append(tuple(column_names))
return db_schema
我得到的变量看起来像这样:
{'Table 1': [('Column 1-1', 'Column 1-2', 'Column 1-3')],
'Table 2': [('Column 2-1', 'Column 2-2')]}
然后我将该模式变量传递给另一个函数,以将每个 table 中的数据转储到元组列表中:
def get_table_data(cursor, schema):
for tbl, cols in schema.items():
sql = "SELECT * from %s" % tbl # Dump data
cursor.execute(sql)
col_data = cursor.fetchall()
for row in col_data:
cols.append(row)
return schema
但是,当我尝试读取返回的变量时,我得到以下信息:
>>> schema2 = get_table_data(cursor, schema)
>>> schema2
Traceback (most recent call last):
File "<input>", line 1, in <module>
MemoryError
TL;DR:当数据太大而无法读取时,有没有办法开始将数据存储在另一个变量中?或者增加内存分配的方法?最后,我想将其转储到 csv 文件或类似的文件中——有没有更直接的方法来解决这个问题?
您可能希望能够将数据流出数据库,而不是一次性加载所有数据。这样您就可以直接将数据写回,而不会一次将太多数据加载到内存中。
最好的方法是使用 generators。
因此,与其像现在这样修改模式变量,不如在从数据库表中读取时产生各种行:
def get_single_table_data(cursor, tbl):
'''
Generator to get all data from one table.
Does this one row at a time, so we don't load
too much data in at once
'''
sql = "SELECT * from %s" % tbl
cursor.execute(sql)
while True:
row = cursor.fetchone()
if row is None:
break
yield row
def print_all_table_data(cursor, schema):
for tbl, cols in schema.items():
print(cols)
rows = get_single_table_data(cursor, tbl)
for row in rows:
print(row)
这显然只是一个示例,但它(理论上)会打印出所有表中的每一行 - 内存中一次不会有超过一行的数据。