【问题标题】:Save SQL to YAML as is按原样将 SQL 保存到 YAML
【发布时间】:2015-08-02 03:20:33
【问题描述】:

我想以我自己的格式将 SQL 保存到 YAML 文件,如下所示:

(1)   
sql: SELECT DISTINCT p.id_product, 
                     p.price AS price, 
                     sp.reduction AS discount
       FROM ....

我使用以下 YAML 设置

yaml.safe_dump(app_config,
               stream,
               indent=4,
               default_flow_style=False,
               encoding='utf-8',
               allow_unicode=True)

但是我得到了 YAML 的“经典”丑陋输出

(2)
sql: SELECT DISTINCT p.id_product, p.price AS price, sp.reduction AS discount, sp.reduction_type
    AS discount_type, pl.description_short AS description FROM ....

有没有办法实现输出#1?

附言。 repr(config) 等于:

{'mapping': {'/*ID_LANG*/': 'AND pl.id_lang IN (/*VALUE*/)', '/*REFERENCE*/': "AND p.reference LIKE '%/*VALUE*/%'", }, 'sql': 'SELECT DISTINCT p.id_product, p.price AS price, sp.reduction AS discount, sp.reduction_type AS discount_type, pl.description_short AS description, pl.name AS name, i.id_image as image, p.reference AS model, m.name AS manufacturer, pl.available_now AS stock_status FROM /*PREFIX*/product p LEFT JOIN /*PREFIX*/product_lang pl ON (p.id_product = pl.id_product) LEFT JOIN /*PREFIX*/manufacturer m ON (m.id_manufacturer = p.id_manufacturer) LEFT JOIN /*PREFIX*/image i ON (i.id_product = p.id_product) LEFT JOIN /*PREFIX*/specific_price sp ON (sp.id_product = p.id_product) LEFT JOIN /*PREFIX*/category pc ON p.id_category_default = pc.id_category WHERE i.cover = 1 /*WHERE*/'}

【问题讨论】:

  • 我们可以假设 {1) 和 (2) 不是 YAML 输出的一部分吗?能否包含 repr(app_config) 的输出?
  • {1} 和 {2} 是真正的 YAML 输出。
  • 我应该引用那个。字符串“(1)”分别。代码标记块中的“(2)”(在“sql”上方)不属于 YAML 块。我试图把它放在块之外,但是你会得到很多空白。

标签: python sql yaml pyyaml


【解决方案1】:

如果您的输入格式是一些未格式化的 SQL(没有换行符和缩进空格),就像您似乎从输出 (2) 中获取的一样,您将永远不会 自动获得不错的输出:

import yaml

sql = ("SELECT DISTINCT p.id_product, "
                      "p.price AS price, "
                      "sp.reduction AS discount, "
                      "sp.reduction_type AS discount_type, "
                      "pl.description_short AS description "
                      "FROM ....")
app_config = dict(sql=sql)
print yaml.dump(app_config)

会给你:

{sql: 'SELECT DISTINCT p.id_product, p.price AS price, sp.reduction AS discount, sp.reduction_type
    AS discount_type, pl.description_short AS description FROM ....'}

如你所见。你可以尝试 使用换行符和缩进手动格式化字符串

app_config = dict(sql="""\
SELECT DISTINCT p.id_product,
                p.price AS price,
                sp.reduction AS discount,
                sp.reduction_type AS discount_type,
                pl.description_short AS description
    FROM ....""")
print yaml.dump(app_config)

但输出也好不了多少:

{sql: "SELECT DISTINCT p.id_product,\n                p.price AS price,\n        \
    \        sp.reduction AS discount,\n                sp.reduction_type AS discount_type,\n\
    \                pl.description_short AS description\n    FROM ...."}


我建议您采用不同的方法并安装一个 sql 格式化程序,如 sqlparseformat-sql 结合 ruamel.yaml(我是 PyYAML 的增强版本的作者),它支持多行文字字符串往返。通过一点帮助,它还可以用于生成正确且更好(如果不是更好)的 YAML 输出。

你可以这样做:

import ruamel.yaml
from ruamel.yaml.scalarstring import PreservedScalarString
import sqlparse

sql = ("SELECT DISTINCT p.id_product, "
       "p.price AS price, "
       "sp.reduction AS discount, "
       "sp.reduction_type AS discount_type, "
       "pl.description_short AS description "
       "FROM ....")
fsql = sqlparse.format(sql, reindent=True, keyword_case="upper").encode('utf-8')

app_config = dict(sql=PreservedScalarString(fsql))
print ruamel.yaml.dump(app_config, Dumper=ruamel.yaml.RoundTripDumper)

并获得YAML literal scalar with preserved newlines

sql: |-
  SELECT DISTINCT p.id_product,
                  p.price AS price,
                  sp.reduction AS discount,
                  sp.reduction_type AS discount_type,
                  pl.description_short AS description
  FROM ....

希望足够接近你想要的。

【讨论】:

    猜你喜欢
    • 2019-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    相关资源
    最近更新 更多