Extensible Generation

10 views
Skip to first unread message

Val Huber

unread,
Mar 10, 2021, 4:39:54 PM3/10/21
to sqlalchemy
I work on ApiLogicServer, which creates a models.py file (then used to create an API and web app).

My objective is to enable users to
  1. Customize models.py (e.g, add hybrid attributes, missing relationships, etc), and 
  2. Preserve these customizations when  the models.py file is later recreated (e.g., the database schema was changed).
I am seeking advice.  I have looked the the following alternatives, but they all present issues:
  1. I'd prefer not rely on a code merge: let the user alter the Customer.py file, then merge customizations when Customer.py is recreated.  Certainly a possibility, but it seems cleaner to keep customization files separate from generated files.  

  2. I have looked into subclassing - e.g., generate Customer_base, let user extend in Customer(Customer_base) so all their customizations are in a separate file.  But, I encountered issues since the relationships are bound to the super classes.  For example, anOrder.Customer returns an instance of Customer_base instead of Customer

  3. I investigated the API sqlalchemy.ext.hybrid.hybrid_property to create hybrid attributes.  I am familiar with hybrids via annotations, but again, I want this to be in a separate file from customer.py.  I am unable to find what to do with the hybrid_property descriptor (assign it to the class?), which raises doubts about this approach.
A clear approach is not emerging, would appreciate some guidance.

Thanks in advance,
Val


Mike Bayer

unread,
Mar 10, 2021, 7:48:23 PM3/10/21
to noreply-spamdigest via sqlalchemy
I would go with "subclassing" but don't map the base class immediately, use a mixin instead - there's examples of this at https://docs.sqlalchemy.org/en/14/orm/declarative_mixins.html .   to ensure the relationships are against the target class, declare them like this:

class MyMixin:
    @declared_attr
    def some_relationship(cls):
         return relationship("Target", ....)

that's the general idea at least.   there's a lot of ways to make things happen with mixins, including using "on mapped" kinds of events for things as well, so see if you can get some of that to work and we can try fixing up the edge cases with events if necessary.
--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper
 
 
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+...@googlegroups.com.

Reply all
Reply to author
Forward
0 new messages