我有一个sql nodata转储,我需要经历它并替换每个create table查询的引擎部分。我被困的一点是,我需要在每个字符串中提及表格名称,我将替换为相应的表格
假设文件如下
CREATE TABLE `tablename1` (
-- #columns and keys
) ENGINE=InnoDB AUTO_INCREMENT=5075 DEFAULT CHARSET=utf8;
CREATE TABLE `tablename2` (
-- #columns and keys
) ENGINE=something AUTO_INCREMENT=55 DEFAULT CHARSET=latin1;
期望的结果是:
CREATE TABLE `tablename1` (
-- #columns and keys
) ENGINE=-myreplacedstring/tablename1; -- #table name 1 is appended to this line
CREATE TABLE `tablename2` (
-- #columns and keys
) ENGINE=myreplacedstring/tablename2; -- #table name 2 is appended to this line
我试过
fin = open('dump.sql','r')
filedata = fin.read()
fin.close()
newdata = re.sub('(?<=ENGINE).*;', '-myreplacedstring-', filedata)
fout = open('fed_dump.sql','w')
fout.write(newdata)
fout.close()
但这只会用固定字符串替换字符串,无论它是哪个表。
我也尝试逐行接近,以便每次通过时都能获取表名,但我不知道如何继续使用它。
with open('dump.sql') as infile, open('dump_fed.sql', 'w') as outfile:
for line in infile:
#tablename= if line contains create table, update tablename, else do nothing
line = re.sub('(?<=ENGINE).*;', '-myreplacedstring-'+tablename, line)
outfile.write(line)
我被困在如何将每个表的表名放入我替换的字符串中。任何帮助表示赞赏。
答案 0 :(得分:1)
您的解决方案肯定会有效,但您可以通过反向引用更快地完成。我测试了这个并且它可以工作(你可以把它变成一个单行,但这样可读性更高):
pattern = r"CREATE TABLE `(.*?)`(.*?)ENGINE=.*?;"
replace_pattern = r"CREATE TABLE `\1`\2ENGINE=-myreplacedstring-\1;"
newdata = re.sub(pattern, replace_pattern, filedata, flags=re.DOTALL)
使用:
我在以下解决方案之前提出过,这是错误的,因为“(?&lt; = ...)”发出信号的后视图必须包含固定长度模式:
pattern = r"(?<=CREATE TABLE `(.*?)`.*?ENGINE=).*;"
newdata = re.sub(pattern, '-myreplacedstring-\1', filedata)
答案 1 :(得分:0)
想出来。不确定这是多么优雅或不易破碎,但它似乎适用于我的情况(采用mysql nodata转储,用联合连接字符串替换引擎,轻松地从一个数据库创建一个完整的联合数据库)。
import re
def gettablename(string, defaultstring):
if 'CREATE TABLE' in string:
return re.search('`(.*)`', string).group(1)
else:
return defaultstring
with open('dump.sql') as infile:
tablename='def' # do i need this default?
for line in infile:
tablename=gettablename(line,tablename)
line = re.sub('(?<=ENGINE).*;', '-myreplacedstring-'+tablename, line)
print line