14

我正在编写一个小型数据库测试套件,它读取带有查询和预期结果的配置文件,例如:

query         = "SELECT * from cities WHERE name='Unknown';"
count         = 0
level         = 1
name          = "Check for cities whose name should be null"
suggested_fix = "UPDATE cities SET name=NULL WHERE name='Unknown';"

这很好用;我使用 Python 的string.partition('=').

我的问题是很长的 SQL 查询。目前,我只是将这些查询粘贴为单行,这是丑陋且不可维护的。

我想找到一种优雅的 Pythonic 方式来读取表达式的右侧,即使跨越多行。

笔记:

  • 我的 SQL 查询可能包含=
  • 我不喜欢在"右手边强制 s 的想法,因为有许多现有文件没有它。

编辑:

ConfigParser很棒,但它迫使我在多行条目的每一行的开头添加一个空格或制表符。这可能是一个巨大的痛苦。

提前致谢,

亚当

4

3 回答 3

23

Python 标准库模块ConfigParser默认支持此功能。配置文件必须是标准格式:

[Long Section]
short: this is a normal line
long: this value continues
    in the next line

上面的配置文件可以用以下代码读取:

import ConfigParser
config = ConfigParser.ConfigParser()
config.read('longsections.cfg')
long = config.get('Long Section', 'long')
于 2010-02-11T17:41:21.003 回答
12

这几乎正​​是使我们切换到YAML的用例(维基百科python 实现文档;您可能希望将JSON作为替代方案)。configparserYAML 比or有一些优势json

  • 人类可读性(对于较大的文件比 JSON 更好);
  • 可以序列化任意 python 对象(这使得它和 一样不安全pickle,但是safe_load在 python 实现中有一个函数可以缓解这个问题)。这对于像datetime对象这样简单的东西已经很有用了。

为了完整起见,主要缺点(IMO):

  • Python 实现比 JSON 实现慢一个数量级;
  • 跨平台的可移植性不如 JSON。

例如

import yaml

sql = """
query         : "SELECT * from cities
WHERE name='Unknown';"
count         : 0
level         : 1
name          : "Check for cities whose name should be null"
suggested_fix : "UPDATE cities SET name=NULL WHERE name='Unknown';"
"""

sql_dict = yaml.safe_load(sql)

print(sql_dict['query'])

印刷

SELECT * from cities WHERE name='Unknown';
于 2010-02-12T10:25:21.200 回答
1

我建议您使用正则表达式...代码可能看起来像这样给您开始:

import re

test="""query = "select * from cities;"
count = 0
multine_query = "select *
from cities
     where name='unknown';"
"""

re_config = re.compile(r'^(\w+)\s*=\s*((?:".[^"]*")|(?:\d+))$', re.M)
for key, value in re_config.findall(test):
    if value.startswith('"'):
        value = value[1:-1]
    else:
        value = int(value)
    print key, '=', repr(value)

这个例子的输出是:

~> python test.py 
query = 'select * from cities;'
count = 0
multine_query = "select *\nfrom cities\n     where name='unknown';"

希望有帮助!

问候,克里斯托夫

于 2010-02-11T19:16:24.307 回答