我正在使用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的“名称”列。但是,当我尝试运行此命令时,出现错误:“类型“ VARCHAR”不存在”。我假设psycopg2的内置格式化程序在不应有VARCHAR类型时将双引号引起来。通常,我自己会解决这个问题,但是文档非常明确指出,永远不要使用Python字符串连接,以免担心SQL注入攻击。安全性是该项目的关注点,因此我想知道是否可以使用pyscopg2以这种方式创建动态类型的表,如果不能,是否存在可以安全地执行此操作的第三方API。谢谢!
丹尼
答案 0 :(得分:1)
我在这方面也遇到了很多麻烦。 sql.Identifier
用于数据类型(INTEGER
、TEXT
等)not 的双引号 SQL 标识符。看起来只是简单的 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...