使用 Python 3.9 插入行 sql 语法错误

Posted

技术标签:

【中文标题】使用 Python 3.9 插入行 sql 语法错误【英文标题】:inserting rows sql syntax error with Python 3.9 【发布时间】:2021-02-03 11:42:03 【问题描述】:

我正在尝试将行插入到我的数据库中。成功建立与数据库的连接。当我尝试插入我想要的行时,我在 sql 中收到错误。该错误似乎来自我的变量“network_number”。我正在运行嵌套 for 循环以遍历从 1.1.1 - 254.254.254 的网络编号范围,并将每个唯一 IP 添加到数据库中。网络号以字符串形式写入,因此网络号列是否应设置为 VARCHAR 或 TEXT 以包含句号/句点?所需的输出是用每个网络号填充我的数据库表。您可以找到分配给变量 sql_query 的 sql 查询。

def populate_ip_table(ip_ranges):
network_numbers = ["", "", ""]
information = "Populating the IP table..."
total_ips = (len(ip_ranges) * 254**2)
complete = 0

for octet_one in ip_ranges:
    network_numbers[0] = str(octet_one)
    percentage_complete = round(100 / total_ips * complete, 2)
    information = f"percentage_complete% complete"
    output_information(information)

    for octet_two in range(1, 254 + 1):
        network_numbers[1] = str(octet_two)

        for octet_three in range(1, 254 + 1):
            network_numbers[2] = str(octet_three)
            network_number = ".".join(network_numbers)
            complete += 1
            sql_query = f"INSERT INTO ip_scan_record (ip, scanned_status, times_scanned) VALUES (network_number, false, 0)"
            execute_sql_statement(sql_query)

information = "100% complete"
output_information(information)

输出

[ * ] Connecting to the PostgreSQL database...
[ * ] Connection successful
[ * ] Executing SQL statement
[ ! ] syntax error at or near ".50"
LINE 1: ...rd (ip, scanned_status, times_scanned) VALUES (1.1.50, false...
                                                         ^

【问题讨论】:

尝试将network_number转换成字符串 为什么不使用Network types? 【参考方案1】:

如文档所述:

这三种类型之间没有性能差异,除了在使用空白填充类型时增加了存储空间,以及在存储到长度受限的列时需要一些额外的 CPU 周期来检查长度。虽然 character(n) 在其他一些数据库系统中具有性能优势,但在 PostgreSQL 中没有这样的优势;事实上 character(n) 通常是三个中最慢的,因为它有额外的存储成本。在大多数情况下,应使用文本或字符变化

Postgresql Docs

我认为您需要使用VARCHAR,因为您的 ip 字符串的长度变化很小。而text实际上是avarchar (no limit),但是如果尝试插入压缩大小大于2712的记录,可能会出现一些与索引相关的问题。

实际上您的问题是,您需要在 network_number 上添加一个额外的单个 qoutes。在 postgresql 中插入值时给你一个字符串。

为了证明这一点,请尝试插入network_number

network_number = "'" + ".".join(network_numbers) + "'"
sql_query = f"INSERT INTO ip_scan_record (ip, scanned_status, times_scanned) VALUES (network_number, false, 0)"

或者:

sql_query = f"INSERT INTO ip_scan_record (ip, scanned_status, times_scanned) VALUES ('network_number', false, 0)"

您也可以使用inet dataType,这样可以省去这个麻烦。

如文档所述:

PostgreSQL 提供数据类型来存储 IPv4、IPv6 和 MAC 地址。最好使用这些类型而不是纯文本类型来存储网络地址,因为这些类型提供输入错误检查以及专门的运算符和函数。

PostgreSQL: Network Address Types

【讨论】:

我使用了 VARCHAR 但我仍然收到错误 实际上,您将错误的数据类型传递给 postgresql。这会导致您的错误。 不,我传递的类型是一个字符串,我检查了 type(network_number) 的输出,它是一个字符串。 我在这里谈论sql_query = f"INSERT INTO ip_scan_record (ip, scanned_status, times_scanned) VALUES (network_number, false, 0)" 你将network_number 作为一个集合或对象传递,但postgresql 等待一个字符串。尝试将其传递为network_number,仅不使用 您需要做的就是在 network_number 上添加一个额外的单个 qoutes。在 postgresql 中插入值时给你一个字符串。为了证明这一点,请尝试插入 network_number,如下所示:sql_query = f"INSERT INTO ip_scan_record (ip, scanned_status, times_scanned) VALUES ('network_number', false, 0)"

以上是关于使用 Python 3.9 插入行 sql 语法错误的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL Append_Values 提示给出错误信息

通过 python informixdb 寻找 Informix 的 SQL 插入语法

MySQL 常用插入语法总结

如何插入包含单引号的字符串

尝试使用多个值插入 SQL Server 时出现不正确的语法错误

SQL Server:使用变量创建表