繁体   English   中英

在表存在之前,如何使用 flask-sqlalchemy 映射表关系?

[英]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.

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