I'm changing my framework to use the SQLAlchemy declarative system internally. However, I want to keep the API the same. Here is how users of my framework declare a foreign key:
from myframework import Model, Link
class Bar(Model)
class Foo(Model):
bar = Link(Bar)
At first I thought I could simply change the implementation of Link to this:
def Link(cls):
return relationship(cls.__name__)
But actually I see that in SQLAlchemy I also need an Integer column that contains the id. So, I think I would need to patch the class at runtime to ensure these 2 attributes are defined. First, I would make a simple definition of Link to store the class it points to:
class Link:
def __init__(self, cls):
self.cls = cls
Then after I import the user's module, I patch all subclasses of Model:
for cls in Model.__subclasses__():
for k, v in list(cls.__dict__.items()):
if isinstance(v, Link):
ClsName = v.cls.__name__
setattr(cls, k, relationship(f'{cls.__module__}.{ClsName}'))
setattr(
cls,
f'{k}_id',
Column(
Integer,
ForeignKey(f'{cls.__tablename__}_{ClsName.lower()}.id'),
),
)
However, I get this:
sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'live_bid.player_id' could not find table 'live_bid_player' with which to generate a foreign key to target column 'id'
I guess I am patching it too late. My next idea is to put this patching code inside the metaclass of Model, but before I go too far down the wrong path I wanted to ask here if there is a better way :)
Thank you!