質問

私は、クエリと期待される結果を含む構成ファイルを読み取る小さな 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';"
助け

希望!

よろしく、 クリストフ

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top