python有一个奇怪的问题,不是不确定这是否与psycopg2有关,还是与python有关的菜鸟错误。
基本上,我有一个功能,可以从csv复制数据并尝试使用psycopg2将其插入pgsql数据库。如果存在数据类型错误,我希望代码尝试对其进行更正,然后重新尝试将数据插入数据库中。这是代码:
def copy(self, csvFile):
error = True
i = 0
while error:
try:
i += 1
print(f'attempt {i}')
self.connect()
csr = self.conn.cursor()
csr.copy_expert("COPY foo.bar FROM STDOUT NULL '' CSV HEADER", csvFile)
except psycopg2.DataError as err:
print(err)
print(err.pgcode)
csr.close()
self.conn.close()
#self.conn.rollback()
if err.pgcode == '22001':
if 'character varying' in err.args[0]:
currlength = re.search(r'\((.*?)\)', err.args[0]).group(1)
newlength = int(currlength) * 2
s = err.args[0].split()
col = s[s.index('column') + 1].replace(':','')
sql = f'alter table foo.bar alter column {col} type varchar({newlength})'
print(f'Column Length too short adjusting {col} from {currlength} to {newlength}\n {sql}')
self.execute(sql)
elif err.pgcode == '22p02':
s = err.args[0].split()
col = s[s.index('column') + 1].replace(':', '')
sql = f'alter table foo.bar alter column {col} varchar(64)'
print(f'numeric column {col} contains text altering to varchar')
self.execute(sql)
else:
self.conn.commit()
csr.close()
error = False
发生的情况是,第一次尝试按预期执行并抛出错误,然后alter table语句正确运行,第二次尝试copy_expert函数不执行任何操作但没有错误,并且在不将csv数据插入数据库的情况下完成了代码。这是显示它第二次尝试的输出。
> attempt 1
> value too long for type character varying(1) CONTEXT: COPY
table, line 3, column id: "12345678"
>
> 22001
> Column Length too short adjusting assetid from 1 to 2
> alter table foo.bar alter column id type varchar(2)
> Executing query alter table foo.bar alter column assetid type varchar(2)
> attempt 2
> Download and insert of file.csv Complete
答案 0 :(得分:1)
因此,在花了大约30分钟的热情走下一条盲巷之后,我认为我找到了问题的根源。它与psycopg2
无关,我也不必称其为菜鸟错误。实际上,我非常确信这与隔离级别有关……不是。
这是文件句柄。 copy_expert
完全读取了文件,因此当psycopg2.DataError
上升时,内部指针位于其末尾。第二次没有任何可读取的内容。
如果将csvFile.seek(0)
放在except
块中,则指针将重置为文件的开头。
except psycopg2.DataError as err:
csvFile.seek(0)
我已经使用您的copy
方法创建了一个小的测试类,并以我认为的方法实现了方法execute
和connect
。
我能够重现您在帖子中描述的行为,并重置except
块中的指针,导致第二次尝试修改后,文件中的数据在数据库中可见列长。