简体   繁体   中英

Flask-SQLAlchemy relationships without classes?

According to the Flask-SQLAlchemy documentation , relationships like "addresses" in the following example expect the class "Address" to exist.

class Person(db.Model):
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(50), nullable=False)
  addresses = db.relationship('Address', backref='person', lazy=True)

class Address(db.Model):
...

However in my case the tables are created at runtime and thus I cannot create classes. Is it possible to use the relationship function without a class? How can I create the table dynamically and tell the relationship function about it? If that is not possible, do I need to dynamically create classes for tables like "Address" in the example?

I solved it using dynamically created classes as suggested by @Wimanicesir but I don't know if a more elegant solution exists:

from flask_appbuilder import Model, Base
from sqlalchemy import Column, Integer, String, ForeignKey, Table,
from sqlalchemy.orm import relationship
import config 
from sqlalchemy import create_engine 

engine = create_engine(config.SQLALCHEMY_DATABASE_URI)

associativeData = [
    ["language","lang"],                                                                                                                                      
    ["license","license"],
    ["operatingsystem","os"],
    ["programminglanguage","plang"],
    ]

def repr(self):
        return self.label

clazzes = []
for data in associativeData:
   clazzes.append(type(data[0], (Base, ),
   {
        "__table__": Table(data[0], Base.metadata,autoload=True,autoload_with=engine),
        "__repr__": repr
   }))

associativeTables = list(map(lambda d: Table('swp_has_'+d[0], Base.metadata,
        Column('swp_suffix', String(200), ForeignKey('softwareproduct.suffix')),
        Column(d[1]+'_suffix', String(200), ForeignKey(d[0]+'.suffix'))
        ),
        associativeData))
  
class Softwareproduct(Model):
    suffix = Column(String(200), primary_key=True)  
    def __repr__(self):
        return self.label

for i in range(len(associativeData)):
    rel = relationship(associativeData[i][0], secondary = associativeTables[i])
    setattr(Softwareproduct,"swp_has_"+associativeData[i][0],rel)

[...]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM