psycopg2.sql使用sql.Identifier插入变量类型导致类型“整数”不存在

时间:2019-04-06 16:24:18

标签: python psycopg2

我试图使用psycopg2.sql动态创建表,我编写了一个函数,该函数接受一个由列名和列的数据类型组成的元组列表,然后创建一个字符串,并使用“ {}”这样的占位符:

create table {} ({} {}, {} {} ...);

我展平了元组列表,以便结果列表中的元素与我想要将它们插入查询字符串中并将该结果列表用作sql.SQL(query)中的参数的顺序相对应。格式(...)

生成的sql.Composed实例如下:

Composed([SQL('create table '), Identifier('games'), SQL(' ( '), Identifier('score_loser'), SQL(' '), Identifier('integer'), SQL(' , '), Identifier('playoffs'), SQL(' '), Identifier('boolean'), SQL(' , '), Identifier('record_loser'), SQL(' '), Identifier('integer[]'), SQL(' , '), Identifier('broadcast'), SQL(' '), Identifier('varchar(20)'), SQL(' , '), Identifier('date'), SQL(' '), Identifier('date'), SQL(' , '), Identifier('id'), SQL(' '), Identifier('varchar (30)'), SQL(' , '), Identifier('home_team'), SQL(' '), Identifier('varchar (50)'), SQL(' , '), Identifier('record_winner'), SQL(' '), Identifier('integer[]'), SQL(' , '), Identifier('winner'), SQL(' '), Identifier('varchar (50)'), SQL(' , '), Identifier('loser'), SQL(' '), Identifier('varchar (50)'), SQL(' , '), Identifier('score_winner'), SQL(' '), Identifier('integer'), SQL(' , primary key ('), Identifier('id'), SQL(') );')])

但是当我尝试执行此sql.composed实例时,出现错误消息“ integer”不是类型,其中“ integer”是我传递给format函数的列表中的元素。

是否也可以使用psycopg2.sql动态传递变量类型,或者如果可以,请告诉我该怎么做?

2 个答案:

答案 0 :(得分:0)

我有类似的问题。我通过混合字符串组成,format()和列表生成器来解决它。

data = (('column_name_1','VARCHAR(2)'), ('column_name_2','INT'))
data = ['%s %s' % (x[0], x[1]) for x in data]
columns_string = ', '.join([x for x in data])

这是columns_string = ' column_name_1 VARCHAR(2),column_name_2 INT '

query = 'CREATE TABLE {}(%s)' % columns_string
query = sql.SQL(query).format(sql.Identifier('test_table'))

如果我们检查查询:

print(query.as_string(conn))

创建表“ test_table”(column_name_1 VARCHAR(2),column_name_2 INT)

我们像cur.execute(query)一样执行它,并且可以正常工作。不是复杂的解决方案,可能不是可靠的解决方案,但是可以。

答案 1 :(得分:0)

我在这方面也遇到了很多麻烦。 INTEGER 用于数据类型(TEXTcolumns 等)not 的双引号 SQL 标识符。看起来只是简单的 SQL 就可以解决问题。

注意在您的代码中,您应该有预定义的 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... 元组,而不是将它们的定义公开给前端。这也是元组在这里很有用的原因,因为它们是不可变的。

  import { interval } from 'rxjs';

  ngOnInit(): void {
      interval(5000).subscribe(() => {
          this.getChatsList();
      });
  }