简体   繁体   English

Python Function 重复使用

[英]Python Function Reuse

I have a function defined as below in my python code:我有一个 function 在我的 python 代码中定义如下:

def insert_source():
    sql = "INSERT INTO public.source (width, height, sha1) " \
          "VALUES (%s, %s, %s)"
    conn = None
    data = widtho, heighto, sha1o
    try:
        # read database configuration
        params = config()
        # connect to the PostgreSQL database
        conn = psycopg2.connect(**params)
        # create a new cursor
        cur = conn.cursor()
        # execute the INSERT statement
        cur.execute(sql, data)
        # commit the changes to the database
        conn.commit()
        print('Source image data successfully imported', sha1o)
        # close communication with the database
        cur.close()
    except (Exception, psycopg2.DatabaseError) as error:
        if str(error) in "duplicate key value violates unique constraint":
            raise
        else:
            print("I've seen this image before, skipping insert")
    finally:
        if conn is not None:
            conn.close()
            return id

if __name__ == '__main__':
    insert_source()

this works fine and inserts that or throws an exception as expected.这可以正常工作并按预期插入或抛出异常。 BUT now later in my script I want to write some more data in a different table within the same db.但是现在稍后在我的脚本中,我想在同一个数据库中的不同表中写入更多数据。 Should I copy/paste the entire function above and rename it or is there a better way to say do most of these things but the sql and data should be X?我应该复制/粘贴上面的整个 function 并重命名它,还是有更好的方法说做大部分这些事情,但 sql 和数据应该是 X?

FWIW duplicating that function results in a Duplicated code fragment (31 lines long) note so it just seems silly to replicate 98% of that code when I need to change 4 lines in total. FWIW 复制 function 会导致Duplicated code fragment (31 lines long)注释,因此当我总共需要更改 4 行时复制 98% 的代码似乎很愚蠢。

you can add arguments to the function for example table_name, things_to_insert, and values.. so your function will be like:您可以将 arguments 添加到 function 中,例如 table_name、thing_to_insert 和 values.. 所以您的 function 将如下所示:

def insert_source(table_name, things_to_insert, values):
    sql = f"INSERT INTO {table_name} {things_to_insert} VALUES {values}"
    conn = None
    data = widtho, heighto, sha1o
    try:
        # read database configuration
        params = config()
        # connect to the PostgreSQL database
        conn = psycopg2.connect(**params)
        # create a new cursor
        cur = conn.cursor()
        # execute the INSERT statement
        cur.execute(sql, data)
        # commit the changes to the database
        conn.commit()
        print('Source image data successfully imported', sha1o)
        # close communication with the database
        cur.close()
    except (Exception, psycopg2.DatabaseError) as error:
        if str(error) in "duplicate key value violates unique constraint":
            raise
        else:
            print("I've seen this image before, skipping insert")
    finally:
        if conn is not None:
            conn.close()
            return id

if __name__ == '__main__':
    table_name = 'public.source'
    thing_to_insert = (width, height, sha1)
    values = '(%s, %s, %s)'
    insert_source(table_name, things_to_insert, values)

this will do exactly what your code does, and you can customize arguments to make the function reusable.这将完全按照您的代码执行,您可以自定义 arguments 以使 function 可重复使用。

BUT, as Ted Klein Bergman said in the comments, this way is great candidate for SQL injections.但是,正如 Ted Klein Bergman 在评论中所说,这种方式非常适合 SQL 注射。 so what you have to do is to make prepared/parametrized queries as Klein suggested.所以你要做的就是按照 Klein 的建议进行准备好的/参数化的查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM