1

我现在有以下问题:

我有一个只有 2 列的数据库表:ID ( primary key, auto increment) 和值 ( varchar(100))。

现在我有一个sql文件来用值填充该表。重点是:首先,文本文件只有单个插入,因此插入的每个值都是单个值。一般不会有问题,如果不是大约 1000 万行...

为了让它更有趣,我有 5 个这样的表和 5 个.sql带有插入语句的文件。

现在我尝试按原样运行 sql 文件,即使只有 100k 行,也需要一个小时......所以插入 1000 万个条目大约需要 100 小时......所有表的 x5 大约需要 500 小时,大约 21 天.. 我不想在这里看到任何事情......

现在从我读过的内容来看,如果一个插入语句包含多个要插入的值,速度会快得多......例如:

insert into knownPasswords3 (password)
values ('! -');

insert into knownPasswords3 (password)
values ('! 3');

insert into knownPasswords3 (password)
values ('! 5');

insert into knownPasswords3 (password)
values ('! ?');

insert into knownPasswords3 (password)
values ('! C');

insert into knownPasswords3 (password)
values ('! c');

会成为:

insert into knownPasswords3 (password)
values ('! -','! 3','! 5','! ?','! C''! c');

作为一个例子......从我读过的内容来看,每个插入语句大约 40 个值将是一个相当不错的值......

所以这就是我想要得到的......从一个包含 400 个单语句(例如)的 sql 文件到一个包含 10 个语句的 sql 文件,每个语句有 40 个值。

现在我已经尝试了很多正则表达式和 Notepad++ 中的不同方法作为示例,但我无法真正让它工作......

然后我虽然如果python可能能够以一种优雅的方式做到这一点(或者直接将它插入到数据库中,或者只是转换文本文件)。我认为插入不会有太大帮助,所以现在我正在寻找一种将文件转换为另一个文件的方法,只是它具有提到的单个语句的减少..

我的伪代码类似于:

open file.sql
i = 0;
for each line in file.sql:
   if i==40:
      i=0
      break
   else:
      remove text "insert into knownPasswords3 (password) values ("
      remove text ");"
      add text ,

但是,我已经尝试过了,只是无法让这些部件正常工作......

任何人都可以让我走上正确的轨道吗?是否有一个库或某事使这更容易?

4

4 回答 4

1

此代码纯粹基于文件处理、列表切片和字符串操作。它读取一个名为“file.sql”的文件,并在名为“file2.sql”的第二个文件中保存每个包含 40 个值的插入语句。

希望这能回答你的问题。

# reading the lines from SQL file
file1 = open('file.sql', 'r')
lines = file1.readlines()
file1.close()

# removing the first line
lines.pop(0)

# getting a list of all the values
list_of_values = []
for i in range(0, len(lines), 3):
  list_of_values.append(lines[i].split("'")[1])  

# setting the limits to 40 elements per insert statement
lowerlimit = -40
upperlimit = 0

# flag to check whether the number of values left is greater than 40
remaining_values = True

# second file to save output
file2 = open('file2.sql', 'w')

while remaining_values:

  # setting flag if remaining values less than 40
  if len(list_of_values)-upperlimit <= 40:
    remaining_values = False

  # updating limits as we move traverse the list
  lowerlimit = upperlimit
  upperlimit = min(upperlimit + 40, len(list_of_values)) 

  # formulating insert statement
  output = 'insert into knownPasswords3 (password)\nvalues '

  # adding 40 values to each insert statement
  if remaining_values == True:
    output += str(list_of_values[lowerlimit:upperlimit]).replace('[','(').replace(']',')') + ";\n\n"
  else:
    output += str(list_of_values[lowerlimit:upperlimit]).replace('[','(').replace(']',')') + ";"

  # writing insert statement to output file
  n = file2.write(output)    

# closing the file
file2.close()

对示例文件进行测试,它提供以下输出:

insert into knownPasswords3 (password)
values ('! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?');


insert into knownPasswords3 (password)
values ('! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3');


insert into knownPasswords3 (password)
values ('! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c');


insert into knownPasswords3 (password)
values ('! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c', '! -', '! 3', '! 5', '! ?', '! C', '! c');
于 2021-01-21T20:43:38.500 回答
1

我认为问题出在您尝试准备的插入语句中。它应该如下所示:

insert into knownPasswords3 (password)
values ('! -'),('! 3'),('! 5'),('! ?'),('! C'),('! c');

现在您插入 6 行 1 列,而您的查询插入 1 行 6 列。

于 2021-01-21T19:12:04.837 回答
0

尝试这个:

infile = open('file.sql', 'r' )

ins_stmnts = {}
for line in infile:
    if 'insert' in line:
      ins_stmnt, vals = line.split('values')
      if ins_stmnt in ins_stmnts.keys():
        ins_stmnts[ins_stmnt].append(vals)
      else:
        ins_stmnts[ins_stmnt] = [vals]

infile.close()

outfile = open("converted.sql", 'w')

for ins_stmnt, vals in ins_stmnts.items():
  val_str = "("
  for i, val in enumerate(vals):
    if i%39==0:
      val = val.rstrip(');\n')
      val = val.lstrip(' (')
      val_str += val
      outfile.write(ins_stmnt + "values " + val_str + ');\n')
      val_str = "("
      break
    else:
      val = val.rstrip(');\n')
      val = val.lstrip(' (')
      val_str += val + ','

  if len(val_str)>1:
    outfile.write(ins_stmnt + "values " + val_str.rstrip(',') + ');\n')

outfile.close()
于 2021-01-21T21:45:29.977 回答
0

你可以调查交易。它们将必须一起执行或不执行的语句组合在一起(有点像将多个语句视为一个语句)。不完全确定它是否是您正在寻找的东西。

于 2021-01-21T19:39:55.613 回答