“错误:整数的输入语法无效:”在 Redshift 表中为 SMALLINT 列插入 NULL 值时?
Posted
技术标签:
【中文标题】“错误:整数的输入语法无效:”在 Redshift 表中为 SMALLINT 列插入 NULL 值时?【英文标题】:"Error: invalid input syntax for integer:" when inserting NULL values for an SMALLINT column in a Redshift table? 【发布时间】:2017-11-27 23:08:54 【问题描述】:我有这个本地定义的 python 函数,在将数据插入红移表时可以正常工作:
def _insert_data(table_name, values_list):
insert_base_sql = f"INSERT INTO table_name VALUES"
insert_sql = insert_base_sql + ','.join([str(row) for row in values_list])
<run_local_python_code_to_execute_insert_sql>
values_list
是一个元组列表,每个元组的元素数量与table_name
中的列数相同(尽管我没有在此函数中明确断言/检查)。但是,我找不到为smallint
列插入NULL
值的方法。这是相关表的架构(在创建表时没有为列分配 DEFAULT
值):
schemaname | tablename | column | type | encoding | distkey | sortkey | notnull
------------+---------------------+--------------+-----------------------+----------+---------+---------+---------
public | table | col1 | bigint | lzo | t | 1 | f
public | table | col2 | date | lzo | f | 2 | f
public | table | col3 | smallint | lzo | f | 3 | f
public | table | col4 | smallint | lzo | f | 4 | f
public | table | col5 | double precision | none | f | 0 | f
public | table | col6 | bigint | lzo | f | 0 | f
public | table | col7 | character varying(48) | bytedict | f | 0 | f
我特别想为col3
和col4
插入NULL
值;我尝试使用 ''
和 'NULL'
创建元组,但遇到此错误:Error: invalid input syntax for integer: "NULL"
。
对于它的价值,这就是 INSERT
语句中清理后的行最终的样子:('bigint_value', 'dt_value', 'NULL', 'NULL', 'double_value', 'bigint_value', 'string_name')
【问题讨论】:
您是否尝试在您希望NULL
s 所在的位置使用None
的值?
是的——这也是我的第一个想法;导致此错误:Error: column "none" does not exist in table_name
(行看起来像('bigint_value', 'dt_value', None, None, 'double_value', 'bigint_value', 'string_name')
)
要插入空值,请使用不带引号的关键字 NULL。
是的-@alecxe 下面的回答有所帮助。远离','.join([str(row) for row in values_list])
并改用占位符。
【参考方案1】:
您所采取的方法本身就很危险。使用字符串连接和格式化构造查询容易出错且不安全——您的查询容易受到SQL injection attacks 的攻击。
相反,正确参数化您的查询,将参数列表作为单独的参数传递给cursor.executemany()
。这是生成占位符的一种,不是很漂亮的方法:
placeholders = ", ".join(["%s"] * len(values_list))
query = f"""
INSERT INTO
table_name
VALUES
(placeholders)
"""
cursor.executemany(query, values_list)
(注意表名不能参数化 - 单独清理和验证)
注意executemany()
的使用——它将为values_list
中的每个元组执行准备好的查询语句。
但是,如果您使用的是 psycopg2
,还有一种更好的方法可以将多条记录插入到表中 - execute_values()
- 看看 this answer。
并且,回到您最初的问题 - 如果您采用这种方法,None
占位符值将被数据库驱动程序自动转换为 'NULL'
字符串。
【讨论】:
注意:sql注入问题;我会纠正的。我最初也尝试使用None
,但遇到了这个错误:Error: column "none" does not exist in table_name
@ScottBorden 对,我怀疑您没有使用参数化查询, None 被插入到查询中作为 None
"keyword" 没有引号 - 因此它被解释为列名而不是列值。请尝试这种方法。以上是关于“错误:整数的输入语法无效:”在 Redshift 表中为 SMALLINT 列插入 NULL 值时?的主要内容,如果未能解决你的问题,请参考以下文章