6

有没有办法从 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-related 命令(即 drop 和 create tableB),但不喜欢在 Python 中对其他表执行任何 SQL 命令。我对如何在 Python 中执行 .sql 文件有一些了解,但不知道如何只执行 .sql 文件中的某些特定命令,如上例所述。让我印象深刻的第一件事是使用正则表达式。但是经过一番争论后,由于我对正则表达式的了解和经验不足,我无法想出正确的正则表达式语法来得到我所期望的。

所以我的问题是,

1)在这里使用正则表达式来只获取所需的命令是正确的方法吗?如果是这样,你能告诉我正确的语法来解析它吗?

2)如果正则表达式在这里不是最好的方法,那么有什么替代解决方案?

3)我在网上找了一些正则表达式测试工具,但都是指定表达式和测试字符串,并突出显示字符串中匹配的数据。我相信如果有一些工具让我首先指定测试字符串,然后手动突出显示字符串中的所需数据,然后反向返回一些适当的语法/表达式,那就太好了。如果您知道此类工具(不限于在线工具!如果是 Macintosh 应用程序我也很高兴),请告诉我...

谢谢。

4

3 回答 3

6

您可以试用sqlparse库,该库将通过解析 SQL 语句来简化您的工作,并让您能够在 SQL 语句中查询和使用标记。它可以是一个 goos 基础,可以过滤掉包含特定令牌的语句,例如tableB您的情况

于 2013-05-27T12:18:18.097 回答
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'.

于 2013-05-27T11:45:03.747 回答
1

虽然我个人认为您应该使用一些解析库来解析 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)
于 2013-05-27T12:37:50.920 回答