我们需要创建一个程序,该程序可以读取 dbf 文件中的更改,然后将更改上传到 MySQL 数据库。我们已经能够将 dbf 文件读取并上传到 MySQL 数据库,但上传过程需要 50 分钟。我们尝试只上传已更改的字段,但遇到一个问题:我们需要关闭并重新打开 dbf 文件。如果在执行此操作时有人进行更改,则它不会注意到已发生更改。
2. 解决方案
2.1 问题分析
dbf 库只会在记录不存在于内存中时从 dbf 文件中提取记录。当你执行
updated = list(source)
实际上是冻结了所有行,因为 updated 是记录的列表(不是列表的列表或元组的列表;这意味着当你稍后尝试比较 source 和 updated 时,你比较的是相同的数据。
2.2 解决方案
为了使 updated 成为 source 的独立实体,可以尝试:
updated = [tuple(row) for row in source]
这将给你一个元组列表,或
updated = [scatter(row, dict) for row in source]
这将给你一个字典列表,这是你字段比较代码进一步所需的内容。
2.3 代码示例
import time
import dbf
import MySQLdb
import os
source_path = r"\\path\to\file"
file_name = "\\test.Dbf"
print("Found Source DBF")
source = dbf.Table(source_path + file_name)
source.open()
print("Opened DBF")
updated = [tuple(row) for row in source]
print("Copied Source")
db = MySQLdb.connect(host="myHost.com", port=3306, user="user", passwd="pass", db="database")
cur = db.cursor()
print("Connected to database")
try:
cur.execute("DROP TABLE IF EXISTS dbftomysql")
except:
db.rollback()
print("Dropped old table")
sql = """CREATE TABLE table(
col1 VARCHAR(200) NOT NULL,
col2 VARCHAR(200),
col3 VARCHAR(200),
col4 NUMERIC(15,2),
col5 VARCHAR(200) )"""
cur.execute(sql)
print("Created new table")
for i, s in zip(source, updated):
query = """INSERT table SET col1 = %s, col2 = %s, col3 = %s, col4 = %s, col5 = %s"""
values = (i["col1"], i ["col2 "], i["col3"], i["col4"], i["col5"])
cur.execute(query, values)
db.commit()
print(i["col1"], i ["col2 "], i["col3"], i["col4"], i["col5"])
print("First Upload Completed")
while True:
for i, s in zip(source, updated):
if i["col1"] != s["col1"]:
print(i["col1"] + " col1Updated")
query = """UPDATE table SET col1= %s WHERE col1= %s"""
values = (i["col1"], s["col1"])
try:
cur.execute(query, values)
db.commit()
except:
db.rollback()
print("No connection to database")
if i["col2"] != s["col2"]:
print(i["col2"] + " col2 Updated for " + i["col1"])
query = """UPDATE table SET col2 = %s WHERE col1= %s OR col1= %s"""
values = (i["col2"], i["col1"], s["col1"])
try:
cur.execute(query, values)
db.commit()
except:
db.rollback()
print("No connection to database")
# etc
updated = [tuple(row) for row in source]
source.close()
source.open()
time.sleep(0.2)
通过使用 updated = [tuple(row) for row in source]
将 updated
设为 source
的独立副本,可以解决不断比较相同数据的错误。