14

我正在使用 sqlalchemy 并尝试将 alembic 集成到数据库迁移中。

我的数据库当前存在,并且定义了许多没有名称的 ForeignKeys。我想添加一个命名约定以允许影响 ForeignKey 列的迁移。

我已将此处给出的命名约定添加到我的 models.py 文件的顶部: SQLAlchemy Naming Constraints

convention = {
      "ix": 'ix_%(column_0_label)s',
      "uq": "uq_%(table_name)s_%(column_0_name)s",
      "ck": "ck_%(table_name)s_%(constraint_name)s",
      "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
      "pk": "pk_%(table_name)s"
              }

DeclarativeBase = declarative_base()


DeclarativeBase.metadata = MetaData(naming_convention=convention)

def db_connect():
   return create_engine(URL(**settings.DATABASE))

def create_reviews_table(engine):
    DeclarativeBase.metadata.create_all(engine)

class Review(DeclarativeBase):

    __tablename__ = 'reviews'

    id = Column(Integer, primary_key=True)
    review_id = Column('review_id', String, primary_key=True)
    resto_id = Column('resto_id', Integer, ForeignKey('restaurants.id'),
            nullable=True)
    url = Column('url', String),
    resto_name = Column('resto_name', String)

我已经按照教程说明设置了 alembic/env.py,将模型的元数据输入到 target_metadata 中。

当我跑

$: alembic current

我收到以下错误:sqlalchemy.exc.InvalidRequestError:包括 %(constraint_name)s 令牌的命名约定要求明确命名约束。

在文档中,他们说“即使我们只使用 Column.unique 标志,相同的功能 [使用命名约定为列生成名称] 也会生效:” 1,所以我认为不应该有问题(他们继续使用未命名的 ForeignKey 举一个例子)。

我是否需要返回并给我所有的约束明确的名称,或者有没有办法自动做到这一点?

4

4 回答 4

6

只需将约定中的“ck”修改"ck": "ck_%(table_name)s_%(column_0_name)s"为。它对我有用。

参阅 sqlalchemy 文档

于 2019-05-06T07:19:11.903 回答
4

此错误消息告诉您的是,您应该明确命名约束。它所指的约束是布尔、枚举等,但不是外键或主键。因此,通过您的表,无论您有布尔值还是枚举,都为其添加名称。例如:

is_active = Column(Boolean(name='is_active'))

这就是你需要做的。

于 2020-03-11T08:51:51.523 回答
0

在每次较旧的迁移中,我都有一些运气naming_convention改回,{}以便它们在正确的历史背景下运行。

仍然完全不确定这可能会产生什么样的有趣副作用。

于 2018-10-13T18:19:47.117 回答
0

这不是一个明确的答案,也无法回答您的直接技术问题,但它可能是一个“哲学问题”吗?就数据库而言,您的 SQLAlchemy 代码是事实的来源,或者 RDMS 是来源。在这种混合情况面前,两者各有一部分,我会看到两条途径:

  1. 您正在探索的一个:您修改数据库的模式以匹配 SQLAlchemy 模型,并使您的 Python 代码成为主控。这是最直观的,但出于技术和管理原因,这可能并不总是可行的。

  2. 接受 RDMS 具有 SQLAlchemy 没有的信息,但幸运的是与日常工作无关。您最好的机会是使用另一个迁移工具 (ETL),它会在迁移之前对数据库进行逆向工程。迁移完成后,您可以将新实例的控制权交还给 SQLAlchemy(这可能需要对新数据库或模型进行一些调整)。

无法判断哪种方法会奏效,因为两者都有自己的挑战。但是我会考虑第二种方法吗?

于 2018-04-25T08:01:46.303 回答