| 168 | |
| 169 | @asynccontextmanager |
| 170 | async def find_insert_problem_async(self, aconn): |
| 171 | try: |
| 172 | async with aconn.transaction(): |
| 173 | yield |
| 174 | except psycopg.DatabaseError: |
| 175 | acur = psycopg.AsyncCursor(aconn) |
| 176 | # Repeat insert one field at time, until finding the wrong one |
| 177 | await acur.execute(self.drop_stmt) |
| 178 | await acur.execute(self.create_stmt) |
| 179 | for i, rec in enumerate(self.records): |
| 180 | for j, val in enumerate(rec): |
| 181 | try: |
| 182 | await acur.execute(self._insert_field_stmt(j), (val,)) |
| 183 | except psycopg.DatabaseError as e: |
| 184 | if len(r := repr(val)) > 200: |
| 185 | r = f"{r[:200]}... ({len(r)} chars)" |
| 186 | raise Exception( |
| 187 | f"value {r!r} at record {i} column0 {j} failed insert: {e}" |
| 188 | ) from None |
| 189 | |
| 190 | # just in case, but hopefully we should have triggered the problem |
| 191 | raise |
| 192 | |
| 193 | def _insert_field_stmt(self, i): |
| 194 | ph = sql.Placeholder(format=self.format) |