For each base class in bases that the _ModelRegistry knows about, create
        a replacement class containing the methods and attributes from the base
        class:
         - the mixin should only extend object (not db.Model)
         - if any of the attributes are MapperProperty instances (relationship,
           association_proxy, etc), then turn them into @declared_attr props

def _convert_bases_to_mixins(self, mcs_args: McsArgs):
        """
        For each base class in bases that the _ModelRegistry knows about, create
        a replacement class containing the methods and attributes from the base
        class:
         - the mixin should only extend object (not db.Model)
         - if any of the attributes are MapperProperty instances (relationship,
           association_proxy, etc), then turn them into @declared_attr props
        """
        def _mixin_name(name):
            return f'{name}_FSQLAConvertedMixin'

        new_base_names = set()
        new_bases = []
        for b in reversed(mcs_args.bases):
            if b.__name__ not in self._registry:
                if b not in new_bases:
                    new_bases.append(b)
                continue

            _, base_name, base_bases, base_clsdict = \
                self._registry[b.__name__][b.__module__]

            for bb in reversed(base_bases):
                if f'{bb.__module__}.{bb.__name__}' in self._base_model_classes:
                    if bb not in new_bases:
                        new_bases.append(bb)
                elif (bb.__name__ not in new_base_names
                        and _mixin_name(bb.__name__) not in new_base_names):
                    new_base_names.add(bb.__name__)
                    new_bases.append(bb)

            clsdict = {}
            for attr, value in base_clsdict.items():
                if attr in {'__name__', '__qualname__'}:
                    continue

                has_fk = isinstance(value, sa.Column) and value.foreign_keys
                if has_fk or isinstance(value, MapperProperty):
                    # programmatically add a method wrapped with declared_attr
                    # to the new mixin class
                    exec(f"""\
@declared_attr
def {attr}(self):
    return value""", {'value': value, 'declared_attr': declared_attr}, clsdict)
                else:
                    clsdict[attr] = value

            mixin_name = _mixin_name(base_name)
            new_bases.append(type(mixin_name, (object,), clsdict))
            new_base_names.add(mixin_name)

        mcs_args.bases = tuple(reversed(new_bases))