【问题标题】:Creating dynamically-typed tables using psycopg2's built-in formatting使用 psycopg2 的内置格式创建动态类型表
【发布时间】:2019-06-12 22:05:24
【问题描述】:

我正在使用 Python 开发一个与 PostgreSQL 数据仓库交互的项目,并且我正在使用 psycopg2 API。我正在寻找创建动态类型的表。

例如:我希望能够执行以下代码:

from psycopg2 import connect, sql

connection = connect(host="host", port="port", database="database", user="user", password="pw")

def create_table(tbl_name, col_name, col_type):
    query = sql.SQL("CREATE TABLE {} ({} {})".format(sql.Identifier(tbl_name), sql.Identifier(col_name), sql.Identifier(column_type)))
    connection.execute(query)

create_table('animals', 'name', 'VARCHAR')

最后得到一个名为“animals”的表,其中包含一个 VARCHAR 类型的列“name”。但是,当我尝试运行它时,我收到一个错误:'类型“VARCHAR”不存在'。我假设 psycopg2 的内置格式化程序在不应该有任何 VARCHAR 类型时将双引号括起来。通常情况下,我会自己解决这个问题,但文档非常清楚地表明,不应该使用 Python 字符串连接,以免受到 SQL 注入攻击。安全性是这个项目的一个问题,所以我想知道是否可以使用 pyscopg2 以这种方式创建动态类型的表,如果没有,是否存在另一个可以安全地执行此操作的第三方 API。谢谢!

丹尼

【问题讨论】:

  • @juanpa.arrivillaga 你能详细说明一下吗?在 psycopg2 指南 (initd.org/psycopg/docs/usage.html) 中,以下代码(包含 .format)被列为正确使用:cur.execute(SQL("INSERT INTO {} VALUES (%s)").format(Identifier('numbers')), (10,))
  • 你是对的
  • @juanpa.arrivillaga 好的,感谢您的澄清。您对我最初的问题有任何进一步的了解吗?我真的很茫然,可以使用任何想法。谢谢!

标签: python sql psycopg2


【解决方案1】:

我在这方面也遇到了很多麻烦。 sql.Identifier 用于双引号的 SQL 标识符,其数据类型(INTEGERTEXT 等)不是。看起来只是简单的 SQL 就可以了。

注意在您的代码中,您应该有预定义的 columns 元组,并且不要将它们的定义暴露给前端。这也是为什么元组在这里很有用,因为它们是不可变的。

import psycopg2.sql as sql

def create_table( name, columns ):
    # name = "mytable"
    # columns = (("col1", "TEXT"), ("col2", "INTEGER"), ...)
    fields = []
    for col in columns:
        fields.append( sql.SQL( "{} {}" ).format( sql.Identifier( col[0] ), sql.SQL( col[1] ) ) )

    query = sql.SQL( "CREATE TABLE {tbl_name} ( {fields} );" ).format(
        tbl_name = sql.Identifier( name ),
        fields = sql.SQL( ', ' ).join( fields )
    )
    print( query.as_string(conn) ) # CREATE TABLE "mytable" ( "col1" TEXT, "col2" INTEGER );
    # Get cursor and execute...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-06-18
    • 2014-03-20
    • 2012-09-28
    • 1970-01-01
    • 2015-06-29
    • 2012-08-09
    • 2011-12-21
    相关资源
    最近更新 更多