Flask-Migrate multidb外键到不同的绑定找不到目标表

时间:2019-06-12 13:57:49

标签: python postgresql flask sqlalchemy flask-migrate

我正在尝试使用flask-sqlalchemy __binds__功能将Flask-Migrate与多个数据库一起使用。尝试在两个不同绑定之间建立外键时,flask db migrate失败,并显示错误sqlalchemy.exc.NoReferencedTableError,即找不到表来建立外键。

我正在使用具有绑定键db1db2的Postgres数据库。请注意,如果外键指向同一绑定(数据库)上的表,则不会发生此错误。

这是一个演示问题的示例应用程序:

app / models.py

from app import db

class People(db.Model):
    __bind_key__ = 'db1'

    id = db.Column(db.Integer, primary_key=True)


class Cats(db.Model):
    __bind_key__ = 'db2'

    id = db.Column(db.Integer, primary_key=True)
    people_id = db.Column(db.Integer, db.ForeignKey('people.id'))
    dogs_id = db.Column(db.Integer, db.ForeignKey('dogs.id'))


class Dogs(db.Model):
    __bind_key__ = 'db2'

    id = db.Column(db.Integer, primary_key=True)

app / init .py

from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app,db)

from app import models

一个config.py文件用于根据环境变量设置sqlalchemy绑定:

config.py

import os
basedir = os.path.abspath(os.path.dirname(__file__))

class Config(object):
    SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')
    SQLALCHEMY_BINDS = {
        'db1': os.environ.get('DATABASE_1_URL'),
        'db2': os.environ.get('DATABASE_2_URL')}

在此示例中,Cats表中的Dogs表中的外键没有错误:

dogs_id = db.Column(db.Integer, db.ForeignKey('dogs.id'))

但是对People表做同样的事情,

people_id = db.Column(db.Integer, db.ForeignKey('people.id')) 运行flask db migrate时导致错误:

sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'cats.people_id' could not find table 'people' with which to generate a foreign key to target column 'id'

诸如this one之类的线程指示应通过包含架构名称或绑定键来建立外键:

people_id = db.Column(db.Integer, db.ForeignKey('db1.people.id'))

但是,这将导致相同的错误:

sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'cats.people_id' could not find table 'db1.people' with which to generate a foreign key to target column 'id'

对此的任何建议将不胜感激!

2 个答案:

答案 0 :(得分:0)

问题是您无法跨数据库定义外键。如果您可以将所有这些表移动到单个数据库中,或者将它们放在不同的模式中,那么就可以了。

答案 1 :(得分:0)

您应该设置schema并设置外键。

class People(db.Model):
    __bind_key__ = 'db1'
    __table_args__ = {'schema': 'db1'}

    id = db.Column(db.Integer, primary_key=True)


class Cats(db.Model):
    __bind_key__ = 'db2'
    __table_args__ = {'schema': 'db2'}

    id = db.Column(db.Integer, primary_key=True)
    people_id = db.Column(db.Integer, db.ForeignKey('db1.people.id'))
    dogs_id = db.Column(db.Integer, db.ForeignKey('db2.dogs.id'))


class Dogs(db.Model):
    __bind_key__ = 'db2'
    __table_args__ = {'schema': 'db2'}

    id = db.Column(db.Integer, primary_key=True)