On Mon, Jan 11, 2021, at 10:20 PM, RexE wrote: > 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 :)
Likely patching too early. For this kind of thing you want to use an event like "mapper_configured" , which will give you a space where a particular mapper is all set up, all the Table objects needed should have been defined, and you can add additional attributes. there's a ten-year-old example of what you are trying to do at https://techspot.zzzeek.org/2011/05/17/magic-a-new-orm/. the code there seems to be mostly still how things work. > > Thank you! > > -- > SQLAlchemy - > The Python SQL Toolkit and Object Relational Mapper > > http://www.sqlalchemy.org/ > > To post example code, please provide an MCVE: Minimal, Complete, and > Verifiable Example. See http://stackoverflow.com/help/mcve for a full > description. > --- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to sqlalchemy+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/sqlalchemy/ee6e67c2-331c-490b-bc66-b91c796b50f6n%40googlegroups.com > > <https://groups.google.com/d/msgid/sqlalchemy/ee6e67c2-331c-490b-bc66-b91c796b50f6n%40googlegroups.com?utm_medium=email&utm_source=footer>. -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/sqlalchemy/e573b16d-e33d-4046-ac2c-efd7aa7701a5%40www.fastmail.com.