[英]How to map table relationships with flask-sqlalchemy, before tables exist?
我在 flask-sqlalchemy 中的表之间创建关系时遇到问题。 我有一个带有项目概述的表,从那里开始我想动态创建与我的项目概述相关的新实验表。 但是,当我尝试定义关系时,sqlalchemy 会引发以下错误:
sqlalchemy.exc.InvalidRequestError: When initializing mapper mapped class Projects->projects, expression 'Experiment_Overview' failed to locate a name ('Experiment_Overview'). If this is a c
lass name, consider adding this relationship() to the <class 'app.Projects'> class after both dependent classes have been defined.
这似乎是因为 Experiment_Overview(db.Model) 类还不存在,这是正确的,因为稍后将通过用户输入动态生成。 我怎样才能减轻这个错误?
import os
from flask import Flask, render_template, redirect, request, url_for
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
Bootstrap(app)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///DATA/DB.db"
db = SQLAlchemy(app)
def TableCreator(tablename):
class Experiment_Overview(db.Model):
__tablename__ = tablename
creation_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
experiment_name = db.Column(db.String(30), unique=False, nullable=False, primary_key=True)
projectname = db.Column(db.String(150), db.ForeignKey('projects.projectname'), nullable=False, unique=True)
return MyTable
class Projects(db.Model):
projectname = db.Column(db.String(150), unique=True, nullable=False, primary_key=True)
creation_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
experiments = db.relationship('Experiment_Overview', backref="experiments", lazy=True, uselist=False)
def __init__(self, owner, projectname, status, created_at):
self.owner=owner
self.projectname=projectname
self.status=status
self.created_at=created_at
db.create_all()
一般来说,您不会动态创建表; 您通常不应该在程序运行时创建或删除表。
此外,我认为创建链接回整个表格的真实关系是不可能的。 关系/外键用于链接表中的行。
别担心,有更简单的方法可以实现您在此处寻找的行为。
从你的问题听起来你可以有多个项目,每个项目可以在项目中有多个实验。
这将使项目与其实验之间的关系成为一对多关系。
如果是这种情况,您将需要一个 Projects 表(您的代码中已经有),并且您还需要一个 Experiments 表。
Projects 表中的每一行代表一个项目。 实验表中的每一行代表一个实验。 Experiments 表将有一列包含链接回实验所链接到的项目的外键。
我已经根据上面链接的 SQLAlchemy 文档中给出的一对多示例代码修改了您的代码。 注意在relationship()
中添加了back_populates
选项,这允许双向了解关系:实验知道它属于哪个项目,而项目知道它有什么实验。
import os
from flask import Flask, render_template, redirect, request, url_for
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
Bootstrap(app)
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///DATA/DB.db"
db = SQLAlchemy(app)
class Projects(db.Model):
__tablename__ = "projects"
projectname = db.Column(db.String(150), unique=True, nullable=False, primary_key=True)
creation_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
experiments = db.relationship("Experiment", back_populates="project")
def __init__(self, owner, projectname, status, created_at):
self.owner=owner
self.projectname=projectname
self.status=status
self.created_at=created_at
class Experiment(db.Model):
__tablename__ = "experiments"
creation_date = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
experiment_name = db.Column(db.String(30), unique=False, nullable=False, primary_key=True)
projectname = db.Column(db.String(150), db.ForeignKey('projects.projectname'), nullable=False)
project = relationship("Project", back_populates="experiments")
db.create_all()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.