使用SQLAlchemy创建表,但推迟索引创建直到数据加载完成

5 投票
1 回答
1185 浏览
提问于 2025-04-18 16:29

我有一个Python文件,这个文件使用SQLAlchemy来定义一个数据库里的所有表格,包括所有相关的索引和外键约束。这个文件大概长这样:

Base = declarative_base()

class FirstLevel(Base):
    __tablename__ = 'first_level'
    first_level_id = Column(Integer, index=True, nullable=False, primary_key=True, autoincrement=True)
    first_level_col1 = Column(String(100), index=True)
    first_level_col2 = Column(String(100))
    first_level_col3 = Column(String(100))

class SecondLevel(Base):
    __tablename__ = 'second_level'
    second_level_id = Column(Integer, index=True, nullable=False, primary_key=True, autoincrement=True)
    first_level_id = Column(None, ForeignKey(FirstLevel.first_level_id, onupdate='cascade', ondelete='cascade', deferrable=True), index=True, nullable=False)
    second_level_col1 = Column(String(100), index=True)
    second_level_col2 = Column(String(100))
    second_level_col3 = Column(String(100))

class ThirdLevel(Base):
    __tablename__ = 'third_level'
    third_level_id = Column(Integer, index=True, nullable=False, primary_key=True, autoincrement=True)
    first_level_id = Column(None, ForeignKey(FirstLevel.first_level_id, onupdate='cascade', ondelete='cascade', deferrable=True), index=True, nullable=False)
    second_level_id = Column(None, ForeignKey(SecondLevel.second_level_id, onupdate='cascade', ondelete='cascade', deferrable=True), index=True, nullable=False)
    third_level_col1 = Column(String(100), index=True)
    third_level_col2 = Column(String(100))
    third_level_col3 = Column(String(100))

...

我可以通过执行以下命令,利用这个文件在Postgres数据库中创建一个新的模式:

engine = create_engine('postgresql://username:password@path_to_database')
Base.metadata.create_all(engine)

问题是,我需要往这个新创建的数据库里加载大量的数据,如果不先去掉索引和外键约束,这个过程会花费很长很长的时间。但是手动去掉这些索引和外键约束,然后在数据插入完后再手动重新创建,实在是太麻烦了,这样一来就失去了使用SQLAlchemy创建数据库模式的便利。

我在想,有没有办法先用SQLAlchemy在数据库中创建表格,然后加载数据,最后再用SQLAlchemy ORM来创建所有的索引和外键约束呢?

1 个回答

3

你可以使用 Alembic 的迁移脚本来实现这个功能。

  1. 首先,创建初始的表格或者删除已有的索引。
  2. 然后,加载数据。
  3. 最后,添加索引。

撰写回答