Я пишу маленький набор тестов DB, который читает конфигурационные файлы с запросами и ожидаемыми результатами, например:
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 способом считать право на выражение, даже если промежутки по многим строкам.
Примечания:
=
"
s вокруг правой стороны, потому что существует много существующих файлов без него.Править:
ConfigParser является большим, но он вынуждает меня добавить пространство или вкладку в начале каждой строки в многострочной записи. Это могло бы быть большой болью.
Заранее спасибо,
Adam
Это почти тот самый вариант использования, который заставил нас перейти на YAML ( Википедия , реализация python , документация ; в качестве альтернативы вы можете посмотреть JSON ). YAML имеет некоторые преимущества перед configparser
или json
:
pickle
, но в реализации python есть функция safe_load
, чтобы решить эту проблему). Это уже полезно для чего-то столь же простого, как объект datetime
. Для полноты картины основные недостатки (IMO):
Например,
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';
Модуль стандартной библиотеки 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')
Я бы посоветовал вам использовать регулярное выражение ... Код может выглядеть так, чтобы дать вам начало:
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';"
Надеюсь, это поможет!
С уважением, Кристоф