我正在寻找创建多态的一对多关系,例如here我很难解释,所以让我使用示例:
假设我们有三个表书籍、杂志、报纸,它们都有标题为标题和文本的列。 文本列有多个翻译,我想通过多态一对多关系存储。
SQL-Alchemy 中的概念:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
class Book(db.Model):
__tablename__ = "books"
id = db.Column(db.Integer, primary_key=True)
author = db.Column(db.String)
# text_translations = db.relationship("Description", backref="book")
class Magazine(db.Model):
__tablename__ = "magazines"
id = db.Column(db.Integer, primary_key=True)
author = db.Column(db.String)
# text_translations = db.relationship("Description", backref="book")
class Newspaper(db.Model):
__tablename__ = "newspapers"
id = db.Column(db.Integer, primary_key=True)
author = db.Column(db.String)
# text_translations = db.relationship("Description", backref="book")
class Translation(db.Model):
__tablename__ = "translations"
id = db.Column(db.Integer, primary_key=True)
# source_type = # This supposed to be either Book, Magazine, Newspaper
# source_id = # This suppossed to be id of the Book/Magazine/Newspaper (depends on source_type)
language = db.Column(db.String) # this chooses language
text = db.Column(db.String) # this is the text in said language
当然,有一个选项可以使翻译类看起来像这样:
class Translation(db.Model):
__tablename__ = "translations"
id = db.Column(db.Integer, primary_key=True)
book_id = db.Column(db.Integer, db.ForeignKey(Book.id))
magazine_id = db.Column(db.Integer, db.ForeignKey(Magazine.id))
newspaper_id = db.Column(db.Integer, db.ForeignKey(Newspaper.id))
language = db.Column(db.String) # this chooses language
text = db.Column(db.String) # this is the text in said language
但是,如果表的数量远多于 3 个,那么效率就低了。 我尝试通过 SQLAlchemy 执行此操作,但我不确定这是否可能,如果在 SQLAlchemy 中确实无法执行此操作,我可以使用哪种替代方法?
你的做法是正确的。你可以试试这个修改后的代码
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import generic_relationship
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
class Translation(db.Model):
__tablename__ = "translations"
id = db.Column(db.Integer, primary_key=True)
source_type = db.Column(db.String)
source_id = db.Column(db.Integer)
language = db.Column(db.String)
text = db.Column(db.String)
class Content(db.Model):
__abstract__ = True
id = db.Column(db.Integer, primary_key=True)
author = db.Column(db.String)
translations = generic_relationship(Translation, source_type, source_id)
class Book(Content):
__tablename__ = "books"
class Magazine(Content):
__tablename__ = "magazines"
class Newspaper(Content):
__tablename__ = "newspapers"