-
-
Notifications
You must be signed in to change notification settings - Fork 209
Description
Python: 3.10.6
Psycopg: 3.0.16
I was handling dates with a custom Loader and Dumper with psycopg3:
class ExceptionDateDumper(DateDumper):
def dump(self, obj):
year = obj.year
month = obj.month
day = obj.day
if year is None and month is None and day is None:
return super().dump(None)
if year < 0:
bc = " BC"
year*=-1
else:
bc = ""
day = 1 if day is None else day
month = 1 if month is None else month
return bytes(f'{year:04}-{month:02}-{day:02}{bc}', encoding='utf-8')I know the code is kinda sloppy, but the problem is that I cannot give None to super().dump()
Also if I do return b'\N' instead which should be the Postgres Null string, it gets converted to \\N when given to the DB (the rest of the null values that I do not try to mess with are still just \N so are handled fine by Postgres). So I assume it tries to escape my value that I pass while I though writing a Dumper like this would not try to do any further processing.
I also tried with \0 for good measure, but of course that didn't work.
In the end I ended up doing this:
#SQLDate is my custom type that I registered with `register_dumper`
date = None if year is None and month is None and day is None else SQLDate(year, month, day)
# Three dots just means more arguments
copy.write_row( (..., date, ...) )I don't like this approach though as I handle None outside the DateDumper.
If I have missed something, hopefully with your help we can update the documentation to make this more clear how it should be handled.
Thank you so much for making this project! :)
EDIT:
I also have a __nonzero__ method in the custom type, but it does not change the handling.
class SQLDate:
def __init__(self, year, month, day):
self.year = year
self.month = month
self.day = day
def __str__(self):
return f'SQLDate({self.year:04}-{self.month:02}-{self.day:02})'
def __nonzero__(self):
if self.year is None and self.month is None and self.day is None:
return False
else:
return True