I am using BULK UPSERT to insert record into new table while data of column is being encrypting by python lib CryptoDome.
here is what I done
def bulk_upsert_query(data, table_name=None):
values_list = []
add = values_list.append
for i in data:
encrypt_user_id = encryption_fnc(str(i.user_id))
add(f"({i.id},'{encrypt_user_id}','{i.name}')")
upsert_sql = r"""insert into upsert_test_table
(id,encrypt_user_id,name)
values
""" + "n, ".join(values_list) + """ ON CONFLICT ON CONSTRAINT
"upsert_test_table_pkey"
DO UPDATE SET
name=excluded.name,
encrypt_user_id=excluded.user_id"""
return upsert_sql
data = data from my old table that have user_id as int(ex: 124,345,786)
in upsert_test_table
table id column is primary key column.
this bulk_upsert_query
fnc will encrypt int user_id and append to values_list then create a upsert query.
As per insertion it works as I expected, but when it comes for update if conflict with id column then as you can see I set encrypt_user_id=excluded.user_id
for user_id column,
it update existing encrypted user_id with int user_id(from old table), because I did not put any encryption fnc here,
Update: user_id column is changeable
So what I want is I want to call my encryption_fnc
in DO UPDATE SET
section,
while it update I also want to do encryption.
Can any one tell me who can I achieve this?
Note: I can do encryption in database site by using pgcrypto
but my requirement is do encryption in python side not database side.
2
Answers
Solved: Sorry I was stupid, I thought
excluded
table is original(input payload) table, but when I replacedexcluded.user_id
withexcluded.encrypt_user_id
and it works, although have no idea how excluded table works.As per the comment:
there is no
user_id
column in that insert payload, soexcluded.user_id
isnull
.ON CONFLICT...DO UPDATE SET encrypt_user_id=excluded.user_id
is inserting anull
rather than the old, unencrypteduser_id
: demoFrom the documentation:
The issue here was that
excluded
was misunderstood and instead used as the preexisting data found already in the table upon conflict, while it’s actually the data that was coming in, as the payload of that insert.It should be enough to correct that one misinterpretation and refer to new/incoming/inserted value as
excluded
, old/existing by the target table name and column: