pgadmin4/web/pgadmin/utils/driver/psycopg3/encoding.py
2025-01-01 11:26:42 +05:30

70 lines
2.3 KiB
Python

##########################################################################
#
# pgAdmin 4 - PostgreSQL Tools
#
# Copyright (C) 2013 - 2025, The pgAdmin Development Team
# This software is released under the PostgreSQL Licence
#
##########################################################################
# Get Postgres and Python encoding
import psycopg
from flask import current_app
encode_dict = {
'SQL_ASCII': ['SQL_ASCII', 'raw-unicode-escape'],
'SQLASCII': ['SQLASCII', 'raw-unicode-escape'],
# EUC_TW Not availble in Python,
# so psycopg3 do not support it, we are on our own
'EUC_TW': ['BIG5', 'big5'],
'EUCTW': ['BIG5', 'big5'],
# psycopg3 do not support unicode
'UNICODE': ['utf-8', 'utf-8']
}
def get_encoding(key):
"""
:param key: Database Encoding
:return:
[Postgres_encoding, Python_encoding] -
Postgres encoding, Python encoding, type cast encoding
"""
#
# Reference: https://www.postgresql.org/docs/11/multibyte.html
#
if key == 'ascii':
key = 'raw_unicode_escape'
try:
postgres_encoding = psycopg._encodings.py2pgenc(key).decode()
except Exception as e:
# For unsupported encodings by psycopg like UNICODE
current_app.logger.error(e)
postgres_encoding = 'utf-8'
python_encoding = psycopg._encodings._py_codecs.get(postgres_encoding,
'utf-8')
_dict = encode_dict.get(postgres_encoding.upper(),
[postgres_encoding,
python_encoding])
return _dict
def configure_driver_encodings(encodings):
# Replace the python encoding for original name and renamed encodings
# psycopg removes the underscore in conn.encoding
# Setting the encodings dict value will only help for select statements
# because for parameterized DML, param values are converted based on
# python encoding of pyscopg's internal encodings dict.
for key, val in encode_dict.items():
_, python_encoding = val
psycopg._encodings._py_codecs[key] = python_encoding
encodings.update((k.encode(), v
) for k, v in psycopg._encodings._py_codecs.items())
psycopg._encodings.pg_codecs = {
v: k.encode() for k, v in psycopg._encodings._py_codecs.items()}