Python 一对多关系|烧瓶炼金术和烧瓶迁移

Python 一对多关系|烧瓶炼金术和烧瓶迁移,python,sqlalchemy,alembic,Python,Sqlalchemy,Alembic,正在尝试在出站电子邮件(子级)、源(父级1)和目标(父级2)之间建立一对多关系。我正在尝试使用flask migrate设置数据库。我正在使用的命令: python manage.py db migrate 获取以下错误: sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'outbound_emails.target_id' could not find table 'targets' with

正在尝试在出站电子邮件(子级)、源(父级1)和目标(父级2)之间建立一对多关系。我正在尝试使用flask migrate设置数据库。我正在使用的命令:

python manage.py db migrate
获取以下错误:

sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'outbound_emails.target_id' could not find table 'targets' with which to generate a foreign key to target column 'id'
以下是我目前掌握的情况:

class Contact(Base):
    __abstract__ = True
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.Text, nullable=False)
    last_name = db.Column(db.Text, nullable=False)
    email = db.Column(db.Text, nullable=False)
    phone = db.Column(db.Text, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow())
    last_activity = db.Column(db.DateTime, default=datetime.utcnow())
    json_data = db.Column(sqlalchemy.dialects.postgresql.JSON)

    def __init__(self, first_name, last_name, email, phone,
                 created_date=datetime.utcnow(), last_activity=datetime.utcnow(), json_data=None):
        if json_data is None:
            json_data = {}
        self.first_name = first_name
        self.last_name = last_name
        self.email = email
        self.phone = phone
        self.created_date = created_date
        self.last_activity = last_activity
        self.json_data = json_data


class Target(Contact):
    __tablename__ = 'targets'
    outbound_emails = db.relationship("OutboundEmail", backref="target", lazy='dynamic')

    @property
    def __repr__(self):
        return '<target_id {}>'.format(self.target_id)


class Source(Contact):
    __tablename__ = 'sources'
    outbound_emails = db.relationship("OutboundEmail", backref="source", lazy='dynamic')

    @property
    def __repr__(self):
        return '<source_id {}>'.format(self.source_id)


class OutboundEmail(db.Model):
    __tablename__ = 'outbound_emails'
    email_id = db.Column(db.Integer, primary_key=True)
    provider_id = db.Column(db.Text, nullable=True)
    source_id = db.Column(db.Integer, db.ForeignKey("sources.id"))
    target_id = db.Column(db.Integer, db.ForeignKey("targets.id"))
    data = db.Column(sqlalchemy.dialects.postgresql.JSON)

    def __init__(self, provider_id, source, target, merge_fields):
        self.provider_id = provider_id
        self.source = source
        self.target = target
        self.data = merge_fields


    @property
    def __repr__(self):
        return '<email_id {}>'.format(self.email_id)
class联系人(基本):
__抽象=真
id=db.Column(db.Integer,主键=True)
first_name=db.Column(db.Text,nullable=False)
last_name=db.Column(db.Text,nullable=False)
email=db.Column(db.Text,null=False)
phone=db.Column(db.Text,null=False)
在=db.Column(db.DateTime,默认值=DateTime.utcnow()处创建)
last_activity=db.Column(db.DateTime,默认值=DateTime.utcnow())
json_data=db.Column(sqlalchemy.dialogs.postgresql.json)
定义初始化(自我、名字、姓氏、电子邮件、电话、,
已创建(日期=datetime.utcnow(),最后一个活动=datetime.utcnow(),json(数据=无):
如果json_数据为无:
json_数据={}
self.first\u name=first\u name
self.last\u name=last\u name
self.email=电子邮件
self.phone=电话
self.created\u date=创建日期
self.last\u活动=last\u活动
self.json_data=json_data
班级目标(联系人):
__tablename_uu='targets'
outbound_emails=db.relationship(“OutboundEmail”,backref=“target”,lazy='dynamic')
@财产
定义报告(自我):
返回“”。格式(self.target\u id)
班级来源(联系方式):
__tablename_uu='sources'
outbound_emails=db.relationship(“OutboundEmail”,backref=“source”,lazy='dynamic')
@财产
定义报告(自我):
返回“”。格式(self.source\u id)
类外部电子邮件(db.Model):
__tablename_uuu='出站电子邮件'
email\u id=db.Column(db.Integer,主键=True)
provider_id=db.Column(db.Text,nullable=True)
source_id=db.Column(db.Integer,db.ForeignKey(“sources.id”))
target_id=db.Column(db.Integer,db.ForeignKey(“targets.id”))
data=db.Column(sqlalchemy.dialogs.postgresql.JSON)
定义初始化(self、提供者id、源、目标、合并字段):
self.provider\u id=provider\u id
self.source=源
self.target=目标
self.data=merge\u字段
@财产
定义报告(自我):
返回“”。格式(self.email\u id)

有人知道我做错了什么吗?谢谢

解决方案可能取决于您试图实现的继承类型,单表继承、具体表继承或联接表继承

考虑到您已经将基类标记为
\u abstract\ucode>,我假设您希望将每个子类映射到它自己的不同表,从而使用具体继承的形式

在这种情况下,您需要在每个子类上显式定义所有列,即使是相同名称的列。因此,至少您需要设置:

id = db.Column(db.Integer, primary_key=True)
在派生类上

除此之外,您可能还需要在子类中设置多态标识,并可能对其进行扩展以允许多态加载。我建议看一看关于这个话题的文章