有没有办法在Python中的.sql文件中执行一些SQL命令,但不是文件中的所有SQL命令?假设我有以下.sql
文件:
DROP TABLE IF EXISTS `tableA`;
CREATE TABLE `tableA`(
some_code
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `tableB`;
CREATE TABLE `tableB`(
some_code
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS `tableC`;
CREATE TABLE `tableC`(
some_code
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
...to be continued...
在这个文件中,我想解析并只运行tableB
相关的命令(即drop和create tableB
),但不喜欢在Python中的其他表上执行任何SQL命令。我对如何从Python中执行.sql文件有一些了解,但不知道如何只执行.sql文件中的一些特定命令,如上例所示。我头脑中的第一件事就是使用正则表达式。但经过一番争吵之后,由于我的正则表达式知识和经验不足,我无法想出正确的正则表达式语法来得到我的预期。
所以我的问题是,
1)这是使用正则表达式获取所需命令的正确方法吗?如果是这样,你能告诉我正确的解析语法吗?
2)如果正则表达式不是最好的方法,那么替代解决方案是什么?
3)我发现了一些在线正则表达式测试工具,但它们都是指定表达式和测试字符串,并突出显示字符串中的匹配数据。我相信如果有一些工具让我首先指定测试字符串,然后手动突出显示字符串中的所需数据,然后不利地返回一些适当的语法/表达式,这是很好的。如果你知道这些工具(对在线工具没有限制!我很高兴,如果是Macintosh应用程序),请告诉我......
感谢。
答案 0 :(得分:4)
您可以尝试通过解析SQL语句来简化工作的sqlparse库,并为您提供在SQL语句中查询和使用令牌的能力。它可以是一个goos基础,用于过滤掉包含特定标记的语句,例如tableB
答案 1 :(得分:1)
虽然正则表达式可能不是正确的工具,但您仍然可以使用它。
>>> statements = """
... DROP TABLE IF EXISTS `tableA`;
...
... CREATE TABLE `tableA`(
... some_code
... ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
...
... DROP TABLE IF EXISTS `tableB`;
...
... CREATE TABLE `tableB`(
... some_code
... ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
...
... DROP TABLE IF EXISTS `tableC`;
...
... CREATE TABLE `tableC`(
... some_code
... ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
... """
>>> regex = r"((?:CREATE|DROP) TABLE (?:IF (?:NOT )?EXISTS )?`tableB`(?:[^;]|(?:'.*?'))*;)"
>>> re.findall(regex, statements, re.I)
['DROP TABLE IF EXISTS `tableB`;', 'CREATE TABLE `tableB`(\nsome_code\n) ENGINE=MyISAM DEFAULT CHARSET=latin1;']
>>>
如果你想知道什么
`(?:[^;]|(?:'.*?'))*`
适用于,它仅用于匹配除;
以外的任何字符,任何次数,包括无
或
字符串文字,这意味着它允许;
在'this is a ;value; for a varchar field'
之类的字符串中匹配。
答案 2 :(得分:0)
虽然我个人认为你应该使用一些解析库来解析SQL的AST,但通过代码查看这个选项也是可行的:
my_sql_code = '''DROP TABLE...''' #big long string, multiline
statements = my_sql_code.split(';')
statements = [s for s in statements if 'tableB' in s]
for s in statements:
execute_sql(s)