I am trying to (programmatically) create partial views of existing SQLAlchemy models, using a metaclass.
A streamlined example, trying to get a subquery view on a model Foo with a relationship bar, would look something like that:
class Bar(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    
class Foo(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    bar_id = db.Column(db.Integer, db.ForeignKey(
"bar.id"))
     bar = db.relationship(Bar, backref='foos')
    
class FooViewMeta(type(db.Model)):
    def __new__(mcs, name, bases, attrs):
        attrs["__table__"] = (select(Foo)
                        .with_only_columns(Foo.id, Foo.bar_id, Foo.bar)
                        .subquery())
        attrs["bar"] = Foo.__mapper__.relationships["bar"]
        attrs["__mapper_args__"] = {"exclude_properties": ["bar"]}
        return super().__new__(mcs, name, (db.Model,), attrs)
class FooView(metaclass=FooViewMeta):
    pass
(Omitting exclude_properties gives me a warning about conflicting columns)
I am able to load FooView and access its bar property fine.
Unfortunately, if I run:
q = Foo.query.options(joinedload(Foo.bar),)
q.first()
I get the following error, which tells me that this is not a correct way to duplicate the mapper for that relationship:
<class 'sqlalchemy.exc.ArgumentError'>: Mapped class Mapper[FooView(anon_1)] does 
not apply to any of the root entities in this query, e.g. Mapper[Foo(foo)]. 
Please specify the full path from one of the root entities to the target attribute. 
Clearly, the re-use of this relationship is confusing the mapper, who tries to use the newer subquery model and fails.
Conversely, if I use:
attrs["bar"] = getattr(Foo, "bar")
The code works for 1-1 relationship, but fails for lazy 1-many…
Is there a clean way to (programmatically) duplicate all relationship from an existing model, over to a new model (that targets the same table and selects a subset of columns as a subquery)?
Note: unfortunately, I am not looking for polymorphic subclassing here (the "view" classes are a subset of columns, not rows), so it does not seem like I can use any of SQLAlchemy mapper options for that…