Implementation in #2389 can be much simpler. I think this works:
def replace_with(self, other):
self.set_columns(**other.asdict())
A lot of work went into making the dictionary representation a solid and efficient way of moving table data around, so we should avoid duplicating its logic.