0
SQLAlchemy 데이터베이스에 추가하려는 일부 ropey 데이터를 정리하려고합니다. 올바른 유형인지 확인합니다. 그래서 저는 예를 들어 문자열을 올바른 열 길이로 자릅니다.setattr 및 __init__을 사용하여 SQLAlchemy 데이터 정리
나는 이것을 시행하기 위해 getattr()
과 setattr()
을 사용하는 생성자를 생성 해 보았습니다. 하지만 몇 가지 이유로 문자열 등 잘린되지 않습니다 .. 어떤 제안?
class Property(Base):
"""
Property details as imported from various Council sources
"""
MAXPROPREFLEN = 20
MAXADDRESSLEN = 100
MAXDESCRIPLEN = 120
MAXPOSTCODELEN = 10
__tablename__ = 'properties'
id = Column(Integer, primary_key=True)
PropertyRef = Column(String(MAXPROPREFLEN)) # Council reference, diffrerent from UPRN
AccountHolder = Column(String(MAXDESCRIPLEN))
Address1 = Column(String(MAXADDRESSLEN))
Address2 = Column(String(MAXADDRESSLEN))
Address3 = Column(String(MAXADDRESSLEN))
Address4 = Column(String(MAXADDRESSLEN))
PostCode = Column(String(MAXPOSTCODELEN), index=True)
UPRN = Column(BigInteger)
Description = Column(String(MAXDESCRIPLEN))
RV = Column(Numeric(10, 0))
Empty = Column(Boolean)
LiableFrom = Column(Date)
EmptySince = Column(Date)
MEBID = Column(Integer) # Key in MEB table if applicable
Authority = Column(Integer) # Key in authorities table
def __init__(self, **kwargs):
"""
Ordinarily we wouldn't require a constructor, but the data from the
various LAs is of such poor quality and the Psycopg2 connector
so strict about types that we have to clean it up. So we need to
truncate overly long strings etc.
"""
for key, value in kwargs.items():
if key == 'PropertyRef':
setattr(self, key, value[:Property.MAXPROPREFLEN] if value else None)
elif key == 'PostCode':
setattr(self, key, value[:Property.MAXPOSTCODELEN] if value else None)
elif key in ['AccountHolder', 'Description']:
if type(value) is str:
setattr(self, key, value[:Property.MAXDESCRIPLEN])
else:
setattr(self, key, None)
elif key in ['Address1', 'Address2', 'Address3', 'Address4']:
setattr(self, key, value[:Property.MAXADDRESSLEN] if value else None)
elif key in ['LiableFrom','EmptySince']:
if type(value) == datetime.datetime:
setattr(self, key, value.date())
elif type(value) == datetime.date:
setattr(self, key, value)
else:
setattr(self, key, None)
if key == 'UPRN':
if type(value) is str:
try:
setattr(self, key, int(value))
except ValueError:
setattr(self, key, None)
elif type(value) is int:
setattr(self, key, value)
else:
setattr(self, key, None)
else:
setattr(self, key, value)
UPDATE는
표트르 Dawidiuk 덕분에, 고정. 지금은
class Property(Base):
"""
Property details as imported from various Council sources
"""
MAXPROPREFLEN = 20
MAXADDRESSLEN = 80
MAXDESCRIPLEN = 80
MAXPOSTCODELEN = 10
__tablename__ = 'properties'
id = Column(Integer, primary_key=True)
PropertyRef = Column(String(MAXPROPREFLEN)) # Council reference, diffrerent from UPRN
AccountHolder = Column(String(MAXDESCRIPLEN))
Address1 = Column(String(MAXADDRESSLEN))
Address2 = Column(String(MAXADDRESSLEN))
Address3 = Column(String(MAXADDRESSLEN))
Address4 = Column(String(MAXADDRESSLEN))
PostCode = Column(String(MAXPOSTCODELEN), index=True)
UPRN = Column(BigInteger)
Description = Column(String(MAXDESCRIPLEN))
RV = Column(Numeric(10, 0))
Empty = Column(Boolean)
LiableFrom = Column(Date)
EmptySince = Column(Date)
MEBID = Column(Integer) # Key in MEB table if applicable
Authority = Column(Integer) # Key in authorities table
@validates('PropertyRef', 'AccountHolder', 'Description',
'Address1', 'Address2', 'Address3', 'Address4', 'PostCode')
def ValidateString(self, key, value):
maxlengths = {'PropertyRef': Property.MAXPROPREFLEN,
'AccountHolder': Property.MAXDESCRIPLEN,
'Description': Property.MAXDESCRIPLEN,
'Address1': Property.MAXADDRESSLEN,
'Address2': Property.MAXADDRESSLEN,
'Address3': Property.MAXADDRESSLEN,
'Address4': Property.MAXADDRESSLEN,
'PostCode': Property.MAXPOSTCODELEN
}
if type(value) is str:
value = value.strip().upper()
if len(value) > maxlengths[key]:
logger.debug("Timmming {} <{}> to <{}> ({} to {} chars)".format(
key, value, value[:maxlengths[key]],
len(value), maxlengths[key]))
return value[:maxlengths[key]]
else:
return None
@validates('LiableFrom', 'EmptySince')
def ValidateDate(self, key, value):
if type(value) == datetime.datetime:
return value.date()
elif type(value) == datetime.date:
return value
else:
return None
@validates('UPRN')
def ValidateInteger(self, key, value):
try:
return int(value)
except:
return None
@validates('RV')
def ValidateFloat(self, key, value):
try:
return float(value)
except:
return None
어떻게 알 수 있습니까?