我是Python和Psycopg2的新手。我花了最后几个小时在该区域的各个页面上进行了搜索,但找不到与我的确切问题完全匹配的内容。还有其他类似的Stackoverflow问题,但它们对我的工作采用不同的方法。
问题是我无法在数据库中获取有效的NULL。它一直将其转换为对于定义为char(1)的数据库列而言太长的字符串。
以下示例代码可用于测试/重新创建:
import psycopg2
import psycopg2.extras
from psycopg2.extensions import AsIs, ISQLQuote
import configparser
config = configparser.RawConfigParser()
config.read('config.cfg')
host = config.get('postgresql', 'host')
port = config.get('postgresql', 'port')
dbname = config.get('postgresql', 'dbname')
user = config.get('postgresql', 'user')
password = config.get('postgresql', 'password')
pg_connection = "host='{0}' dbname='{1}' user='{2}'
password='{3}'".format(host, dbname, user, password)
INSERT_SQL = "INSERT INTO test_table(region, country_code, comms_type, frequency_units) values %s"
class Myclass():
def __init__(self):
self.region = 'ABC'
self.country_code = 'XX'
self.comms_type = 'MST'
# This works and is a valid value...
self.frequency = 'V'
# The following does not work
# BUT None is also valid value for frequency and should
# be translated to a NULL value in the database
# This is the part I cant get this part to work
self.frequency = None
def __str__(self):
return f'Region: {self.region} Country: {self.country_code} Airport: {self.airport_icao}'
def __len__(self):
return 1
def __getitem__(self, key):
return self
def __conform__(self, protocol):
if protocol is ISQLQuote:
return AsIs(f"'{self.region}', '{self.country_code}', '{self.comms_type}', '{self.frequency}'")
def initDBTable():
conn = None
try:
conn = psycopg2.connect(pg_connection)
cur = conn.cursor()
cur.execute("""
DROP TABLE IF EXISTS test_table;
CREATE TABLE test_table(
id SERIAL PRIMARY KEY,
region varchar(3) NOT NULL,
country_code varchar(2) NOT NULL,
comms_type varchar(3),
frequency_units char(1)
);
""".format())
conn.commit()
cur.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
def store_data(alist):
conn = None
sql = INSERT_SQL
try:
conn = psycopg2.connect(pg_connection)
id = 1
with conn.cursor() as cursor:
psycopg2.extras.execute_values(cursor, sql, alist, template=None, page_size=200)
conn.commit()
conn.close()
except (Exception, psycopg2.DatabaseError) as error:
print(error)
finally:
if conn is not None:
conn.close()
def main():
print('Preparing the database')
initDBTable()
objlist = []
mydata = Myclass()
if mydata:
# in the real code the list is several thousand items
objlist.append(mydata)
store_data(objlist)
if __name__ == "__main__":
main()
代码中的注释解释了预期的结果
感谢所有帮助!