1

我们正在尝试使用 hylang 作为 DSL 来处理一些金融业务流。我们试图将业务规则用作 JSON,但使用 hy 语言切换到 DSL。现在我们需要像之前的 JSON-B 项一样将 s-expression 项持久化到 postgreSQL 中。有没有标准的方法可以做到这一点,或者我们必须使用文本字段来代替?

以前的:

  "conditions": {
    "all": [
        {
            "name": "order_create_date",
            "value": 1620675000,
            "operator": "greater_than_or_equal_to"
        },
        {
            "name": "order_create_date",
            "value": 1624217400,
            "operator": "less_than_or_equal_to"
        }
  }

当前的:

(defn check_condition [params] (
                            and (> params.order_create_date "2021/06/22") (< params.order_create_date "2021/07/22"))

)

4

2 回答 2

3

确实没有标准的方法来做到这一点。Hy 或 Postgres 方面并没有什么特别的实现。除非你有大量的这些,或者它们非常大,或者你想对它们进行某种花哨的搜索或索引,否则将它们存储为文本就可以了。事实上,我更喜欢平面文件而不是数据库。

另一种选择是利用 Postgres 的 JSON 支持并设计您自己的小方法来在 Hy 模型树和 JSON 之间进行转换。例如,Hy 表达式可以表示为 JSON 数组。Python 的json库可以帮助解决这个问题,default例如JSONEncoder.

于 2021-05-18T12:12:41.573 回答
0

有2个解决方案:

  1. 使用像 'sexpdata' 这样的库来解析和解析 S-Expressions 到/来自 Python 列表,然后使用 JSON 加上一些自定义 enc/dec。

  2. 使用 pyparsing 将 S-Expression 解析为 Python 列表,然后使用 json。

    import pyparsing as pp
    import json
    
    LP = pp.Literal("(").suppress()
    RP = pp.Literal(")").suppress()
    String = pp.Word(pp.alphanums + '_,.#@<>=+=/*%[]')
    SingleQuoteString = pp.QuotedString(quoteChar="'", unquoteResults=False)
    DoubleQuoteString = pp.QuotedString(quoteChar='"', unquoteResults=False)
    QuotedString = SingleQuoteString | DoubleQuoteString
    Atom = String | QuotedString
    SExpr = pp.Forward()
    SExprList = pp.Group(pp.ZeroOrMore(SExpr | Atom))
    SExpr << (LP + SExprList + RP)
    
    
    def to_json(expr: str) -> str:
        return json.dumps(SExpr.parseString(expr).asList())
    
    
    def from_json(val: str) -> str:
        if isinstance(val, list):
            return f"({' '.join(from_json(e) for e in val)})"
        else:
            return str(val)
    
于 2021-05-22T09:14:57.083 回答