stmt = attrs.field(default=None)
cols = attrs.field(default=None)
+ def report_nonprintable(self, chars):
+ if chars.isprintable():
+ return ''
+
+ positions = []
+ values = []
+ for pos, char in enumerate(chars, start=1):
+ if not char.isprintable():
+ positions.append(str(pos))
+ values.append(char.encode(errors='ignore').hex())
+
+ return (' [Note: The character(s) in position(s)'
+ f' {", ".join(positions)}'
+ f' are non-printable, in hex: {", ".join(values)}]')
+
def report_bad_cols(self, qualified_table, bad_cols, quotecols):
if quotecols:
detail = ('<p>The following columns are not in the ({0})'
' or the table has column names containing'
' upper case characters, or you do not have'
' permission to access the columns:</p><ul>')
- detail = detail.format(markupsafe.escape(qualified_table))
+ detail = [detail.format(markupsafe.escape(qualified_table))]
for bad_col in bad_cols:
- detail += '<li>{0}</li>'.format(markupsafe.escape(bad_col))
- detail += '</ul>'
+ detail.append(f'<li>{markupsafe.escape(bad_col)}'
+ f'{self.report_nonprintable(bad_col)}</li>')
+ detail.append('</ul>')
raise upload_ex.BadHeadersError(
'Header line contains unknown column names',
- detail=detail)
+ detail=''.join(detail))
def build_insert_stmt(
self, tuh, data, qualified_table, quotecols, column_quoter):