【问题标题】:Join condition reading form YAML file coming as String以字符串形式加入 YAML 文件的读取条件
【发布时间】:2024-01-24 02:11:01
【问题描述】:

在我的项目中,我想在YAML 文件中维护连接条件(pyspark 数据帧连接条件)。

示例连接条件如下所示。

table1.col1 == table2.col1

在 YAML 中,条件是这样的。

cond: table1.col1 == table2.col1

当我从 YAML 读取连接条件时。我得到如下(字符串类型)。

table1.col1 ==  table2.col1

条件转换为字符串(用单引号括起来)。

为了解决这个问题(为了获得准确的文字而不是字符串),我尝试了以下方法。但是,它们不起作用。

1)

import ast
final_cond = ast.literal_eval(cond)

2)

import json
final_cond = json.loads(cond)

我在阅读时需要确切的文字而不是字符串,或者将这种相等连接条件从字符串转换为文字。

注意:要应用连接条件,一种方法是编写这样的代码。

joined = table1.join(table2, [table1.col1 == table2.col1], "inner")

但是,如果我从 YAML 中获取条件,joined 将变为如下。

joined = table1.join(table2, ['table1.col1 == table2.col1'], "inner")  # notice the enclosed single quotes 

引号(单引号或双引号)是失败的原因。

目前,YAML 文件只有以下对。如果这种方法可行,我将添加更多类似的条件。

cond: table1.col1 ==  table2.col1

【问题讨论】:

  • 您期望得到什么? YAML 只是字符串。 YAML 文件的示例也可能会有所帮助
  • 我更新了问题,进一步解释了问题。
  • YAML 文件是一个字符串。您阅读的所有内容都是字符串。它没有类型或“条件”的概念。您将需要进行转换。某些语言中存在的某种形式的评估。

标签: python yaml


【解决方案1】:

在 YAML 中,table1.col1 == table2.col1 是一个标量。标量是默认加载到字符串中的字符序列。

在 Python 中,table1.col1 == table2.col2 是一个被解析为 AST 一部分的表达式。在标准实现中,AST被处理成字节码并放入.pyc文件中。这一切都发生在任何代码执行之前,这意味着它发生在代码读取您的 YAML 文件之前。这就是为什么你不能直接从 YAML 注入 AST 的一部分。

但是,您可以在运行时访问 Python 的解析和解释工具(简单地说,这就是今天所谓的“解释”语言与编译语言的区别)。这意味着你可以写

joined = table1.join(table2, [eval('table1.col1 == table2.col1')], "inner")

eval() 将给定的字符串解析为 Python 源代码,然后在当前上下文中对其进行评估(即将所有名称解析为调用站点上可见的本地变量)。这样,您可以评估从 YAML 文件中获得的字符串,就好像它是 Python 源代码的一部分一样。

请注意eval() 基本上与整个 Python 语言一样强大,因此在使用它之前,请确保它永远不会在您无法完全控制的任何字符串上执行。如果你曾经在用户输入时执行eval(),用户基本上可以执行你的应用程序中的任何代码,这是一个严重的安全漏洞。

【讨论】:

  • 谢谢@flyx。这正是我正在寻找的。它按预期工作。