【问题标题】:How to send a list of data to postgresql from python and then iterate trough that list into an insert postgresql function?如何从 python 将数据列表发送到 postgresql,然后将该列表迭代到插入 postgresql 函数中?
【发布时间】:2020-12-02 09:32:57
【问题描述】:

我已经有一个 python 代码将数据发送到我也创建的 postgresql 函数,但现在我想向该函数发送一个列表,但我不确定如何实际创建那种 postgresql 函数。

将插入一行的 Postgresql 函数如下所示。但我想从 python 发送一个数据列表,然后在这个函数内部循环遍历该列表。

        CREATE OR REPLACE FUNCTION asg.insert_asg(
        recommendation_account text,
        recommendation_region text,
        recommendation_time text,
        asg_name text,
        asset_id text,
        launch_configuration_name text,
        min_size integer,
        max_size integer,
        desired_capacity integer,
        default_cooldown integer,
        availability_zones text,
        load_balancers_classic text,
        load_balancers_classic_missing text[],
        load_balancers_target_groups text,
        load_balancers_target_groups_missing text[],
        instances text[],
        create_time text,
        tags text[],
        termination_policies text,
        new_instances_protected_from_scale_in boolean,
        cloud_fit boolean,
        recommendations_content text[])
        RETURNS integer
        LANGUAGE 'plpgsql'
        COST 100
        VOLATILE PARALLEL UNSAFE
    AS $BODY$
    DECLARE 
            new_asg_id integer;
            
    BEGIN
        INSERT INTO asg.asg(recommendation_account, recommendation_region, recommendation_time, asg_name, asset_id, launch_configuration_name, min_size, max_size, desired_capacity, default_cooldown, availability_zones, load_balancers_classic, load_balancers_target_groups, create_time, termination_policies, new_instances_protected_from_scale_in, cloud_fit, load_balancers_classic_missing, load_balancers_target_groups_missing, instances, tags)
            VALUES(recommendation_account, recommendation_region, recommendation_time, asg_name, asset_id, launch_configuration_name, min_size, max_size, desired_capacity, default_cooldown, availability_zones, load_balancers_classic, load_balancers_target_groups, create_time, termination_policies, new_instances_protected_from_scale_in, cloud_fit, load_balancers_classic_missing, load_balancers_target_groups_missing, instances, tags)
            RETURNING asg.asg_id
            INTO new_asg_id;
        
        INSERT INTO asg.recommendations(recommendations_content, asg_id)
            VALUES (recommendations_content, new_asg_id);
        
        RETURN new_asg_id;
    END;
    $BODY$;

ALTER FUNCTION asg.insert_asg(text, text, text, text, text, text, integer, integer, integer, integer, text, text, text[], text, text[], text[], text, text[], text, boolean, boolean, text[])
    OWNER TO postgres;

Python 代码如下所示

def insert_asg():
    #INSERT db from input json file to posgre sql table
    json_inputs = read_input_json(request.get_json())
    print(json_inputs)

    try:
        conn = connect()
        cur = conn.cursor()

        inserted_rows = 0
        query = "select asg.insert_list_asg("
        for json_input in json_inputs:    
            inserted_rows += 1
            for param in json_input:            #For Loop for transfering string that was read from json file, to string that can be applied to postgre function
                if type(param) is list:
                    param = (str(param)).replace("'", "")
                    param = (str(param)[1:-2]).replace("{", "[").replace("}","]")
                    param = "{" + param + "}"

                if type(param) is not str:
                    param = str(param)
                else:
                    param = "'" + param + "'"

                if param == "None":
                    param = "null"
                
                query = query + param + ", "

            commas = query.rfind(",") #This will return the index of the last comma, and in the next line we will remove it as that is last paramater we sent to postgres function
            query = query[:commas]
        query += ")"

        print(query)   
        # cur.execute(query)
        # conn.commit()   
        
        cur.close()
        return json.dumps({'success':True, 'inserted_rows':inserted_rows}), 200, {'ContentType':'application/json'} 

我实际上不需要 python 代码的帮助,只需要使用 postgresql,但如果有人需要查看它,我会在此处添加它。

postgresql版本为12.4,python版本为3.7

【问题讨论】:

  • 你的代码可以用于SQL注入。你确定要这个吗?你的 json 对象是什么样子的?你可以把它放到你的数据库函数中,让 PostgreSQL 为你处理它
  • 不用担心sql注入。你说我可以发送一个包含多个对象的原始json(一个对象==一行)并且postgresql可以处理它?这是它的样子:pastebin.com/WuY8YRQx
  • 这不是一个有效的 json 对象。但是,是的,您可以在 SQL 中完成。

标签: python sql database postgresql insert


【解决方案1】:

带有有效 json 的小例子:

WITH i(j) AS (
    SELECT
        '{
        "recommendation_account": "foo",
        "recommendation_region": "None",
        "recommendation_time": "13:39:00",
        "recommendations": ["bar","baz"]
        }'::json
), step_1 AS (
    INSERT INTO asg.asg (
        recommendation_account,
        recommendation_region,
        recommendation_time)        
    SELECT  NULLIF(j #>> '{recommendation_account}', 'None')
            , NULLIF(j #>> '{recommendation_region}', 'None')
            , (NULLIF(j #>> '{recommendation_time}', 'None'))::time -- Will fail when not valid
    FROM    i
    RETURNING asg.asg_id
)
INSERT INTO asg.recommendations(asg_id, recommendations_content)
SELECT  asg_id,
        recommendations_content
FROM    step_1
    ,   i
    ,   json_array_elements_text(j #> '{recommendations}') jae(recommendations_content)
RETURNING id;

但您必须确保您有一个有效的 json 对象,并且所有内容也与表中的数据类型匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多