1

我正在使用 sqlparse 来尝试查找特定语句。

代码:

import sqlparse

text = 'SELECT * FROM dbo.table'
parse = sqlparse.parse(text)
pizza = [t for t in parse[0].tokens if t.ttype in (sqlparse.tokens.Keyword)]

我明白了

[<DML 'SELECT' at 0x9f12318>, <Keyword 'FROM' at 0x9f12548>]

但我真正想要的是返回表名:

dbo.table

我怎样才能做到这一点?我的最终目标是解析 sql 脚本文件夹并查找参考资料和其他详细信息。

4

1 回答 1

2

如果您打印每个令牌

>>> pprint(parse[0].tokens)

[<DML 'SELECT' at 0x7fc278c9eb50>,
 <Whitespace ' ' at 0x7fc278c9eba8>,
 <Wildcard '*' at 0x7fc278c9ec00>,
 <Whitespace ' ' at 0x7fc278c9ec58>,
 <Keyword 'FROM' at 0x7fc278c9ecb0>,
 <Whitespace ' ' at 0x7fc278c9ed08>,
 <Identifier 'dbo.ta...' at 0x7fc278cb3628>]

你会看到这dbo.table实际上不是关键字,而是标识符

逻辑下一步:过滤标识符

>>> pprint([t for t in parse[0].tokens if t.ttype in (sqlparse.tokens.Identifier)])

但这给了AttributeError: 'module' object has no attribute 'Identifier'. 如果您查看sqlparse 的源代码,您会发现 sql.tokens 中没有标识符,您无法对其进行过滤。(代码错误?也许忘了实现?)

但是,如果您打印每个令牌的 ttype

>>> pprint([t.ttype for t in parse[0].tokens])

[Token.Keyword.DML,
 Token.Text.Whitespace,
 Token.Wildcard,
 Token.Text.Whitespace,
 Token.Keyword,
 Token.Text.Whitespace,
 None]

您将看到它们都有一个有效的 Token 作为 ttype,除了dbo.table,即None.

知道了这一点,我们可以过滤它的标记并得到我们想要的结果:

>>> print([t for t in parse[0].tokens if t.ttype is None])

[<Identifier 'dbo.ta...' at 0x7f6ae0318628>]

并获得名称:

>>> print([t.to_unicode() for t in parse[0].tokens if t.ttype is None][0])
u'dbo.table'

或者

>>> print([str(t) for t in parse[0].tokens if t.ttype is None][0])
'dbo.table'

注意[0]最后的,以获得列表理解产生的数组中的第一个也是唯一的项目

于 2015-04-15T19:16:04.000 回答