PostgreSQL架构的Alembic迁移问题和无效的一对多关系

4 投票
1 回答
2884 浏览
提问于 2025-04-18 18:54

我在Postgres里创建了一个数据库和模式(schema)。我有了我的模型,当我运行 python manager.py db migrate 这个命令时,使用的是Flask-Migrate,但出现了下面的错误。不过, db init 这个命令是可以正常工作的。

sqlalchemy.exc.ProgrammingError: (ProgrammingError) no schema has been selected to create in

现在,当我在我的模型里添加 __tablename____table_args__ = {"schema": "name_of_schema"} 时,我在运行 db initdb migrate 时都遇到了下面的错误:

sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'deploy.instance_id' could not find table 'instance' with which to generate a foreign key to target column 'id'

不过,我的关系看起来是没问题的。我见过很多例子,它们在SQLite上运行得很好,而且没有使用Flask-Migrate。

我有三个表,简单说一下(省略了大部分列):

class Application(db.Model):
    __tablename__ = 'application'
    __table_args__ = {"schema":"v1"}
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=False)
    instances = db.relationship('Instance', backref='application', lazy='dynamic')

    def __repr__(self):
        return '<ID %r>' % (self.id)


class Instance(db.Model):
    __tablename__ = 'instance'
    __table_args__ = {"schema":"v1"}
    id = db.Column(db.Integer, primary_key=True)
    host = db.Column(db.String(80), unique=False)
    application_id = db.Column(db.Integer, db.ForeignKey('application.id'))
    deploys = db.relationship('Deploy', backref='instance', lazy='dynamic')

    def __repr__(self):
        return '<ID %r>' % (self.id)


class Deploy(db.Model):
    __tablename__ = 'deploy'
    __table_args__ = {"schema":"v1"}
    id = db.Column(db.Integer, primary_key=True)
    tag = db.Column(db.String(80), unique=False)
    instance_id = db.Column(db.Integer, db.ForeignKey('instance.id'))

    def __repr__(self):
        return '<ID %r>' % (self.id)

它们之间的关系是:

  • 应用程序与实例之间是一对多的关系(一个应用程序可以有多个实例)
  • 实例与部署之间也是一对多的关系(一个实例可以有多个部署)

当我去掉所有关系,创建一个独立的表时,仍然出现第一个错误: sqlalchemy.exc.ProgrammingError: (ProgrammingError) no schema has been selected to create in。这是什么问题,我该怎么解决呢?

1 个回答

8

Postgresql 有一个叫“默认模式”的概念,这个模式是通过 SEARCH_PATH 来设置的。听起来你连接的用户没有配置这个。你可以去看看 Postgresql 网站上的客户端连接默认设置

关于外键错误,当你在使用 Table 时明确指定了 schema 参数,那么在 ForeignKey 对象中也需要指定这个名字:

ForeignKey('myschema.mytable.id')

撰写回答