Classe creazione dinamica in SQLAlchemy
-
03-10-2019 - |
Domanda
Abbiamo bisogno di creare classi SQLAlchemy per accedere a più fonti di dati esterne che aumenteranno di numero nel corso del tempo. Usiamo la base dichiarativa per i nostri modelli ORM core e so che possiamo specificare manualmente nuove classi ORM utilizzando l'autoload = True per generare automaticamente la mappatura.
Il problema è che abbiamo bisogno di essere in grado di generare dinamicamente portandoli qualcosa di simile:
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
stored={}
stored['tablename']='my_internal_table_name'
stored['objectname']='MyObject'
e trasformandolo in qualcosa di simile in modo dinamico:
class MyObject(Base):
__tablename__ = 'my_internal_table_name'
__table_args__ = {'autoload':True}
Non vogliamo le classi di persistere più a lungo del necessario per aprire una connessione, eseguire le query, e quindi chiudere la connessione. Pertanto, idealmente, siamo in grado di mettere gli elementi nella variabile "memorizzato" di cui sopra in un database e tirare come necessario. L'altra sfida è che il nome dell'oggetto (ad esempio "MyObject") può essere utilizzato su diverse connessioni in modo da non possiamo definire una volta e tenerlo intorno.
Qualche suggerimento su come questo potrebbe essere realizzato sarebbe molto apprezzato.
Grazie ...
Soluzione
È possibile creare in modo dinamico MyObject
utilizzando il chiamata 3-argomento per type
:
type(name, bases, dict)
Return a new type object. This is essentially a dynamic form of the
class statement...
Ad esempio:
mydict={'__tablename__':stored['tablename'],
'__table_args__':{'autoload':True},}
MyObj=type(stored['objectname'],(Base,),mydict)
print(MyObj)
# <class '__main__.MyObject'>
print(MyObj.__base__)
# <class '__main__.Base'>
print(MyObj.__tablename__)
# my_internal_table_name
print(MyObj.__table_args__)
# {'autoload': True}