使用Python错误填充PostgreSQL数据库

时间:2017-08-21 02:01:14

标签: python database postgresql sql-injection

我正在尝试填充数据库,但是语法错误。

我有多个包含数据的列表,其中有几个列表包含这些列表。

injury_act_1 = ('2017-01-16 15:36:38','Injury','Unsafe Act', 'TRUE', 'FALSE', 'While lifting a 50 lb item from the floor onto their wokrstation, the employee felt a sharp pain in their lower back.','The employee ran out of room on their workstation because the takeaway conveyor was inoperable')

重复10次。对于那些审核的伤害,审核和行动项目,有更多行动项目清单。

我有一个将这些插入我的数据库的功能。

def populate():
    params = config()
    # connect to the PostgreSQL server
    conn = psycopg2.connect("dbname = safety")
    cur = conn.cursor()

    for i in range(len(injuries)):
        incident = (
            """
            INSERT INTO incident (
                            date_time,
                            incident_type,
                            incident_cat,
                            injury,
                            property_damage,
                            description,
                            root_cause
                            )
                VALUES (
                    """+ injuries[i][0] +""",
                    """+ injuries[i][1] +""",
                    """+ injuries[i][2] +""",
                    """+ injuries[i][3] +""",
                    """+ injuries[i][4] +""",
                    """+ injuries[i][5] +""",
                    """+ injuries[i][6] +"""
            """)

        cur.execute(incident)
        print("Injury case added!")

        action_items = (
            """
            INSERT INTO action_items (
                            case_id,
                            finding,
                            corrective_action
                            )
                VALUES (
                    """+ (i+1) +""",
                    """+ injuries[i][4] +". "+ injuries[i][5] +""",
                    """+ actions[i] +""",
                    )

            """
            )

        cur.execute(action_items)
        print("Action item added!")

    for j in range(len(audits)):
        audit = (
            """
            INSERT INTO audit (
                            date_time,
                            type,
                            que_1,
                            que_2,
                            que_3,
                            ans_1,
                            ans_2,
                            ans_3,
                            )
                VALUES (
                    """+ str(audits[i][0]) +""",
                    """+ audits[i][1] +""",
                    """+ audits[i][2] +""",
                    """+ audits[i][3] +""",
                    """+ audits[i][4] +""",
                    """+ audits[i][5] +""",
                    """+ audits[i][6] +""",
                    """+ audits[i][7] +"""
            """
            )

        cur.execute(audit)
        print("Audit added!")

        action_items_a = (
            """
            INSERT INTO action_items (
                            audit_id,
                            finding,
                            corrective_action
                            )
                VALUES (
                    """+ (i+1) +""",
                    'Audit deficiency',
                    """+ actions_a[i] +""",
                    )
            """
            )

        cur.execute(action_items_a)
        print("Action item added!")

    cur.close()
    conn.commit()

populate()

我一直收到这个错误:

Traceback (most recent call last):
    File "database_populator.py", line 204, in <module>
        populate()
    File "database_populator.py", line 137, in populate
        cur.execute(incident)
psycopg2.ProgrammingError: syntax error at or near "15"
Line 12:        2017-01-16 15:36:38,
                            ^

2 个答案:

答案 0 :(得分:1)

如果您仍想自己构建查询字符串(这是一个坏主意),请将日期括在引号中:

"""
    ....
    VALUES (
                '"""+ injuries[i][0] +"""',
                '"""+ injuries[i][1] +"""',
                '"""+ injuries[i][2] +"""',
                '"""+ injuries[i][3] +"""',
                '"""+ injuries[i][4] +"""',
                '"""+ injuries[i][5] +"""',
                '"""+ injuries[i][6] +"""'
        """)

更好的是,使用列表解析构建查询:

"""
    ....     
    VALUES(""" + ",".join("'{}'".format(injury) for injury in injuries[i]) + ")"

答案 1 :(得分:1)

退一步看看你是如何形成查询的。尽量避免使用字符串连接进行查询构建,特别是对于任何类型的用户提供的输入。它不仅容易出错(如您所见),还有a security nightmare

您的代码应使用psycopg2's bind parameter support,看起来更像:

incident = (
            """
            INSERT INTO incident (
                            date_time,
                            incident_type,
                            incident_cat,
                            injury,
                            property_damage,
                            description,
                            root_cause
                            )
                VALUES (""" + (["%s"] * 7).join(", ") + ")"
    cur.execute(incident, injuries)

这样它就可以让psycopg2处理转义和格式化。

如果需要,您可以写出七个文字%s,例如%s, %s, %s, ...。我只是喜欢上面的表格。

这样一来,如果有人欺骗你的应用程序接受injuries中的字符串,比如说');DROP TABLE incident;--,那么你就不会遇到这样的问题。