【问题标题】:How to write a string that could be None to '%s' to a file (python)如何将可能为“%s”的字符串写入文件(python)
【发布时间】:2016-03-15 20:39:10
【问题描述】:

我正在尝试将字符串写入文件。该文件将是对 Microsoft 的 SQL 服务器的查询,因此它必须遵循特定的格式。这就是我的问题所在。

假设其余的代码是正确的,我的写方法是这样的:

file.write("INSERT INTO SAMPLE_TABLE (int_value, string_value, comment)\n"
           "VALUES (%d, '%s', '%s')\n\n" 
           % (row["int_value"], row["string_value"], row["comment"]))

如您所见,我需要在%s 周围加上引号,因为这是查询的语法。我还应该提到我正在开发一个 GUI。用户可以选择输入评论。如果用户没有输入任何内容,row["comment"] 将为 None。但是,因为我在%s周围有引号,所以它会写'None',这将是数据库中与None相对的字符串,在数据库中转换为NULL,这就是我想要的。

我可以这样做:

if row["comment"] is None:
    file.write("INSERT INTO SAMPLE_TABLE (int_value, string_value, comment)\n"
               "VALUES (%d, '%s', %s)\n\n" 
               % (row["int_value"], row["string_value"], row["comment"]))
else:
    file.write("INSERT INTO SAMPLE_TABLE (int_value, string_value, comment)\n"
           "VALUES (%d, '%s', '%s')\n\n" 
           % (row["int_value"], row["string_value"], row["comment"]))

但那是两行代码。如果后来我意识到不止一个值可能是 None 怎么办?我必须检查每一个案例!我需要让这个动态化。

感谢任何帮助。

【问题讨论】:

    标签: python sql python-3.x


    【解决方案1】:

    这个怎么样?

    comment_str = "None" if row["comment"] is None else "'{}'".format(row["comment"])
    file.write("INSERT INTO SAMPLE_TABLE (int_value, string_value, comment)\n"
               "VALUES (%d, '%s', %s)\n\n" 
               % (row["int_value"], row["string_value"], comment_str))
    

    【讨论】:

      【解决方案2】:

      您可以使用任何 python mysql 模块及其游标选项

      cursor.mogrify(query, args)
      

      如果您已经在使用它。 它会根据类型正确转义所有内容。

      如果你想手动做,那么你可以做一个简单的

      row['comment'] if row['comment'] is None else "'".join(['',row['comment'],''])
      

      查询前

      【讨论】:

      • 如果注释为空,会导致sql查询出错,得不到需要的结果。
      • 这可行,但你可以这样做而不是加入:"'{}'".format(row['comment'])
      • 有时加入速度更快。我知道我知道过早的优化,但仍然。 stackoverflow.com/questions/3055477/…
      • join 在这种情况下不会更快,实际上会慢得多。
      【解决方案3】:

      不添加引号,然后用带引号的注释替换它会怎样(双重替换,但可以在一行中完成)?

      row = {"comment": "abc"}
      comment = row.get("comment") # Note, bracket lookup would have thrown a KeyError, not returning None
      values = "%d, '%s', %s" % (1, "string_value", "'%s'" % comment if comment is not None else None)
      print values
      

      哪个会打印 1, 'string_value', 'abc'1, 'string_value', None

      然后使用 VALUES = (%s) % values 替换值

      请注意,如果您只是保留,您实际上甚至不需要将 VALUES 分离到另一个替换中

      comment = row.get("comment")
      # In your string:
      VALUES = (%s) % ("%d, '%s', %s" % (row["int_value"], row["string_value"], "'%s'" % comment if comment is not None else None))
      

      这是一个基本的例子:

      >>> comment = None
      >>> 'Values = (%s)' % ("'%s'" % comment if comment is not None else None)
      'Values = (None)'
      >>> comment = "test"
      >>> 'Values = (%s)' % ("'%s'" % comment if comment is not None else None)
      "Values = ('test')"
      >>> comment = "" # For empty comments, thanks to @Bharel for pointing this out
      >>> 'Values = (%s)' % ("'%s'" % comment if comment is not None else None)
      "Values = ('')"
      

      【讨论】:

      • 如果评论为空,这将导致 None。
      • @Bharel,这就是我们想要的,对吧?因为如果我们得到一个'None',它将被视为数据库中的一个字符串(注意,Values = (%s) 中没有引号),但如果有评论,它们会被添加)。编辑哦,没关系,我现在明白你的意思了。
      • @U 不完全是。我们希望空 cmets 为空,而不是 None
      • @Bharel,我明白你现在的意思了,这是有道理的,请参阅编辑后的答案:)
      【解决方案4】:

      为什么不直接插入

      if row["comment"] is not None:
          row["comment"] = "'%s'" % row["comment"]
      
      file.write(...
      

      它为您提供您想要的自定义行为,并且不需要重复任何代码

      【讨论】:

      • 您是否有理由不能将if row["comment"]: 列为您的第一行?如果row["comment"] 不是None,这将评估为True
      • @Igor if row 也会发生在空评论的情况下。不好。这个答案的问题是它编辑了评论。
      • @Igor 正如 Bharel 所说,这会将空字符串映射到“None”,这不是指定的行为
      【解决方案5】:

      你可以试试

      file.write("INSERT INTO SAMPLE_TABLE (int_value, string_value, comment)\n"
             "VALUES (%d, '%s', '%s')\n\n" 
             % (row["int_value"], row["string_value"], row["comment"] or 'NULL'))
      

      【讨论】:

      • 这没有得到所需的结果。它在内部将其格式化为'NULL'
      【解决方案6】:

      我会将repr(row["comment"])%s 一起使用。它为您提供围绕字符串的引号,但仅保留 None 文字。

      >>> 'VALUES (%s)' % repr(None)
      'VALUES (None)'
      >>> 'VALUES (%s)' % repr("string")
      "VALUES ('string')"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-02-08
        • 1970-01-01
        • 2011-01-30
        • 1970-01-01
        • 2015-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多