パイソン:キーごとに複数行の構成ファイルを読み取る
-
20-09-2019 - |
質問
私は、クエリと期待される結果を含む構成ファイルを読み取る小さな 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 クエリです。現在、これらのクエリをワンライナーとして貼り付けているだけですが、見苦しく、メンテナンスが困難です。
たとえ複数行にまたがる場合でも、式の右側を読み取るためのエレガントで Python 的な方法を見つけたいと考えています。
ノート:
- 私の SQL クエリには
=
- 強制するという考えは好まない
"
右側のあたりにあるのは、これがない既存のファイルがたくさんあるためです。
編集:
構成パーサー これは素晴らしいことですが、複数行のエントリの各行の先頭にスペースまたはタブを追加する必要があります。これは大きな苦痛かもしれません。
前もって感謝します、
アダム
解決
これは、ほぼ正確に、私たちが切り替えたユースケースです。 YAML (ウィキペディア, Pythonの実装, ドキュメンテーション;見てみたいかもしれません JSON 代替案として)。YAML にはいくつかの利点があります configparser
または 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';
他のヒント
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';"
助け希望!
よろしく、 クリストフ
所属していません StackOverflow