这一切都有点模糊,因为该计划是相当深入的,但坚持我,因为我会尽量解释它。我编写了一个程序,它接受一个.csv
文件,并将其转换为MySQL数据库的INSERT INTO
语句。例如:
ID Number Letter Decimal Random
0 1 a 1.8 A9B34
1 4 b 2.4 C8J91
2 7 c 3.7 L9O77
会导致插入语句如下:
INSERT INTO table_name ('ID' int, 'Number' int, 'Letter' varchar(). 'Decimal', float(), 'Random' varchar()) VALUES ('0', '1', 'a', '1.8', 'A9B34');
然而,并非所有
.csv
文件都具有相同的列标题,但它们需要插入到同一个表中。对于没有特定列标题的文件,我想插入一个
VÔ GIÁ TRỊ
值来显示这一点。例如:
假设第一个
.csv
文件A包含以下信息:
ID Number Decimal Random
0 1 1.8 A9B34
1 4 2.4 C8J91
第二个
.csv
文件B具有不同的列标题:
ID Number Letter Decimal
0 3 x 5.6
1 8 y 4.8
在转换成
INSERT
语句并放入数据库之后,理想情况下应该是这样:
ID TableID Number Decimal Letter Random
0 A 1 1.8 NULL A9B34
1 A 4 2.4 NULL C8J91
2 B 3 5.6 x NULL
3 B 8 4.8 y NULL
现在我可能会在这里失去你。
为了完成我需要的工作,我首先获取每个文件,并创建
.csv
文件的所有列标题的主列表:
def createMaster(path):
global master
master = []
for file in os.listdir(path):
if file.endswith('.csv'):
with open(path + file) as inFile:
csvFile = csv.reader(inFile)
col = next(csvFile) # gets the first line of the file, aka the column headers
master.extend(col) # adds the column headers from each file to the master list
masterTemp = OrderedDict.fromkeys(master) # gets rid of duplicates while maintaining order
masterFinal = list(masterTemp.keys()) # turns from OrderedDict to list
return masterFinal
它将从多个
.csv
文件中获取所有列标题,并将它们按顺序组合到主列表中,而不重复:
['ID', 'Number', 'Decimal', 'Letter', 'Random']
这为我提供了
INSERT
语句的第一部分。现在我需要将
VALUES
部分添加到语句中,所以我一次获取并列出每个
.csv
文件的每行中的所有值。为每一行创建一个临时列表,然后将该文件的列标题列表与所有文件的列标题主列表进行比较。然后它遍历主列表中的每一项,并尝试获取列列表中同一项的索引。如果在列列表中找到该项,则会将同一索引处的行列表中的项插入到临时列表中。如果找不到项,则将
'NULL'
插入临时列表。一旦它完成了临时列表,它就会以正确的MySQL语法将列表转换为字符串,并将其附加到
.sql
文件中进行插入。代码中有相同的想法:
def createInsert(inPath, outPath):
for file in os.listdir(inpath):
if file.endswith('.csv'):
with open(inPath + file) as inFile:
with open(outPath + 'table_name' + '.sql', 'a') as outFile:
csvFile = csv.reader(inFile)
col = next(csvFile) # gets the first row of column headers
for row in csvFile:
tempMaster = [] # creates a tempMaster list
insert = 'INSERT INTO ' + 'table_name' + ' (' + ','.join(master)+ ') VALUES ' # SQL syntax crap
for x in master:
thử:
i = col.index(x) # looks for the value in the column list
r = row[i] # gets the row value at the same index as the found column
tempMaster.append(r) # appends the row value to a temporary list
except ValueError:
tempMaster.append('NULL') # if the value is not found in the column list it just appends the string to the row master list
values = map((lambda x: "'" + x.strip() + "'"), tempMaster) # converts tempMaster from a list to a string
printOut = insert + ' (' + ','.join(values) + '):')
outFile.write(printOut + '\n') # writes the insert statement to the file
终于到了提问的时候了。
这个程序的问题是
createInsert()
从tempMaster列表中获取所有行值,并通过行将它们与
'
标记连接起来:
values = map((lambda x: "'" + x.strip() + "'"), tempMaster)
这一切都很好,除了MySQL希望插入
VÔ GIÁ TRỊ
值,并且只插入
VÔ GIÁ TRỊ
thay vì
'NULL'
.
如何获取组装的行列表并搜索
'NULL'
字符串并将其更改为
VÔ GIÁ TRỊ
?
我有两个不同的想法:
我可以沿着这几行做一些事情,从
VÔ GIÁ TRỊ
标记中提取
'
字符串并替换它。
def findBetween(s, first, last):
thử:
start = s.index(first) + len(first)
end = s.index(last, start)
return s[start:end]
except ValueError:
print('ERROR: findBetween function failure.')
def removeNull(aList):
tempList = []
for x in aList:
if x == 'NULL':
norm = findBetween(x, "'", "'")
tempList.append(norm)
khác:
tempList.append(x)
return tempList
或者我可以将
VÔ GIÁ TRỊ
值添加到列表中,而不必从
'
开始。这在
createInsert()
函数中。
for x in tempMaster:
if x == 'NULL':
value = x
tempMaster.append(value)
khác:
value = "'" + x + "'"
tempMaster.append(value)
values = map((lambda x: x.strip()), tempMaster)
printOut = insert + ' (' + ','.join(values) + ');')
outFile.write(printOut + '\n')
但是,我认为这两种方法都不可行,因为它们会显著地减慢程序的速度(较大的文件会导致
MemoryError
)。所以我要征求你的意见。我很抱歉,如果这是混淆或难以遵循。请让我知道,如果是这样的话,我可以做些什么来让你更容易理解,并祝贺你把事情做到底!
thay vì
values = map((lambda x: "'" + x.strip() + "'"), tempMaster)
把这个
values = map((lambda x: "'" + x.strip() + "'" if x!='NULL' else x), tempMaster)
biên tập
感谢您接受/支持我的简单技巧,但我不确定这是否是最佳的。
在更全球化的范围内,您可以避免使用map/lambda(除非我遗漏了什么)。
for row in csvFile:
values = [] # creates the final list
insert = 'INSERT INTO ' + 'table_name' + ' (' + ','.join(master)+ ') VALUES ' # SQL syntax crap
for x in master:
thử:
i = col.index(x) # looks for the value in the column list
r = row[i] # gets the row value at the same index as the found column
value.append("'"+r.strip()+"'") # appends the row value to the final list
except ValueError:
value.append('NULL') # if the value is not found in the column list it just appends the string to the row master list
然后正确地填充
giá trị
,节省内存和CPU。
Tôi là một lập trình viên xuất sắc, rất giỏi!