Introduce an Attribute object to handle the type casting dance

Depends on #15429 and includes the changes from that PR as well. There's a lot more that can be moved to these, but this felt like a good place to introduce the object. Plans are:

- Remove all knowledge of type casting from the columns, beyond a
  reference to the cast_type
- Move type_cast_for_database to these objects
- Potentially make them mutable, introduce a state machine, and have
  dirty checking handled here as well
- Move `attribute`, `decorate_attribute`, and anything else that
  modifies types to mess with this object, not the columns hash
- Introduce a collection object to manage these, reduce allocations, and
  not require serializing the types
Agreed, not happy with defaults right now, planning much more work on those specifically. Needed to cut the PR at some point. Would rather this stay as close to the original structure as possible for the time being.