简体   繁体   English

如何将数据列表从 python 发送到 postgresql,然后将该列表迭代到插入 postgresql function?

[英]How to send a list of data to postgresql from python and then iterate trough that list into an insert postgresql function?

I already have a python code that send the data to the postgresql function that i also created, but now i want to send a list to that function, but I'm not sure how to actually create that kind of postgresql function.我已经有一个 python 代码将数据发送到我也创建的 postgresql function,但现在我想发送一个列表到那个 function,但我不确定如何实际创建那种 postgresql 88340040.658988

Postgresql Function that will insert one row looks like this.将插入一行的 Postgresql Function 如下所示。 But i want to send a list of data from python and then loop trough that list inside of this function.但我想从 python 发送一个数据列表,然后在这个 function 中循环遍历该列表。

        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 code looks like this 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'} 

I actually dont need help with python code, only with postgresql, but i added it there just if anyone need to take a look on it.实际上,我不需要 python 代码方面的帮助,仅需要 postgresql 代码方面的帮助,但我将其添加到那里,以防有人需要查看它。

Version of postgresql is 12.4 and version of python is 3.7 postgresql的版本是12.4,python的版本是3.7

Small example with valid json:有效 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;

But you have to be sure that you have a valid json object and all content also matches the datatypes in your tables.但是你必须确保你有一个有效的 json object 并且所有内容也与你的表中的数据类型相匹配。

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

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