0

insert_bulk

.

def insert_bulk(products: list):
    try:
        sql = """
        INSERT INTO product(
        id, created_date_time, name, expiration_date
        )
        SELECT
        id, NOW() AT TIME ZONE 'Asia/Seoul', name, expiration_date
        FROM (VALUES %s)
        AS products_insert (
            id,
            name,
            expiration_date
        );
        """

        products_insert = [[value for value in product.values()] for product in products]
        # products_insert
        # [['1','apple', None],['2', 'banana', None],['3', 'meat', None], ...]
        with Connector.connect() as connection:
            with connection.cursor() as cursor:
                psycopg2.extras.execute_values(
                    cursor,
                    sql,
                    products_insert,
                    page_size=500,
                )
                affected_row_count = cursor.rowcount
        print(affected_row_count, "products inserted successfully")
    except (Exception, Error) as error:
        print(
            "[product_repository] Error while insert_bulk",
            error,
        )

Connector

import psycopg2
from stock.properties.properties import properties

class Connector:

...

    @staticmethod
    def connect():
        connection = psycopg2.connect(**properties.database)
        return connection

When I try to insert None into expiration_date, the following error occurs.

column "expiration_date" is of type date but expression is of type text
HINT: You will need to rewrite or cast the expression.



I solved the problem by using type casting in update.
(expiration_date = product_update.expiration_date::date)

sql = """
    UPDATE product
    SET
    id = product_update.id,
    name = product_update.name,
    expiration_date = product_update.expiration_date::date
    FROM (VALUES %s)
    AS product_update (
        id,
        name,
        expiration_date
    ) 
    WHERE product_update.id = product.id;
    """

But this way didn't work in insert.

So How can I insert None into date type?

5
  • Can't this be simplified to INSERT INTO product (id, name, expiration_date) VALUES % ? Pretty sure the way you are doing it now is turning None into 'None'. Commented Aug 10, 2022 at 18:02
  • Missed it the first time, this is the problem ['3', 'meat', 'None']. Something in products or products.values() is creating a string 'None' instead of None. Commented Aug 10, 2022 at 18:27
  • @AdrianKlaver Oh, I make a typo in comment. The actual data is None. Commented Aug 11, 2022 at 1:33
  • @AdrianKlaver And I edit my code to add createdDateTime column. How can I simplify in this case? And what do you think of using the template argument? template='(%s, %s, %s::date)') Commented Aug 11, 2022 at 1:53
  • A quick test shows that changing the template worked. Commented Aug 11, 2022 at 15:39

1 Answer 1

1

template argument is effective

with Connector.connect() as connection:
            with connection.cursor() as cursor:
                psycopg2.extras.execute_values(
                    cursor,
                    sql,
                    products_insert,
                    template='(%s, %s, %s::date)'
                    page_size=500,
                )
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.