Import sqlalchemy导入导出在IntegrityError上失败

Import sqlalchemy导入导出在IntegrityError上失败,import,sqlalchemy,Import,Sqlalchemy,我正在使用序列化程序转储和加载编写sqlalchemy导入/导出脚本。 出口工作正常,但我在进口方面有问题,主要是因为外键问题。 我使用sorted_tables根据依赖关系对表列表进行排序,这样可以确保不会出现跨表外键问题,但是否存在处理内部外键(指向自身的表)的类似方法 我基本上在考虑两种可能的解决方案: 找到一种基于依赖项对行进行排序的方法 禁用所有约束->插入数据->启用所有约束 再次 但我不知道该怎么做 表格示例: class Employee(Base): __tablena

我正在使用序列化程序转储和加载编写sqlalchemy导入/导出脚本。 出口工作正常,但我在进口方面有问题,主要是因为外键问题。 我使用sorted_tables根据依赖关系对表列表进行排序,这样可以确保不会出现跨表外键问题,但是否存在处理内部外键(指向自身的表)的类似方法

我基本上在考虑两种可能的解决方案:

  • 找到一种基于依赖项对行进行排序的方法
  • 禁用所有约束->插入数据->启用所有约束 再次
  • 但我不知道该怎么做

    表格示例:

    class Employee(Base):
        __tablename__ = "t_employee"
    
        id = sa.Column(Identifier, sa.Sequence('%s_id_seq' % __tablename__), primary_key=True, nullable=False)
        first_name = sa.Column(sa.String(30))
        last_name = sa.Column(sa.String(30))
        manager_id  = sa.Column(Identifier, sa.ForeignKey("t_employee.id", ondelete='SET NULL'))
    
    这是我的剧本:

    def export_db(tar_file):
        print "Exporting Database. This may take some time. Please wait ..."
    
        Base.metadata.create_all(engine)
        tables = Base.metadata.tables
    
        with tarfile.open(tar_file, "w:bz2") as tar:
            for tbl in tables:
                print "Exporting table %s ..." % tbl
                table_dump = dumps(engine.execute(tables[tbl].select()).fetchall())
    
                ti = tarfile.TarInfo(tbl)
                ti.size = len(table_dump)
                tar.addfile(ti, StringIO(table_dump))
    
        print "Database exported! Exiting!"
    
        exit(0)
    
    def import_db(tar_file):
        print "Importing to Database. This may take some time. Please wait ..."
    
        print "Dropping all tables ..."
        Base.metadata.drop_all(engine)
    
        print "Creating all tables ..."
        Base.metadata.create_all(engine)
        tables = Base.metadata.sorted_tables
    
        with tarfile.open(tar_file, "r:bz2") as tar:
            for tbl in tables:
                try:
                    entry = tar.getmember(tbl.name)
                    print "Importing table %s ..." % entry.name
                    fileobj = tar.extractfile(entry)
                    table_dump = loads(fileobj.read(), Base.metadata, db)
                    for data in table_dump:
                        db.execute(tbl.insert(), strip_unicode(dict(**data)))
                except:
                    traceback.print_exc(file=sys.stdout)
                    exit(0)
            db.commit()
    
        print "Database imported! Exiting!"
    
        exit(0)
    

    对于批量转储,标准技术是禁用约束,执行导入,然后重新启用它们。您还可以获得更快的插入性能。

    对于批量转储,标准技术是禁用约束,执行导入,然后重新启用它们。您还可以获得更快的插入性能。

    那太好了,但是在sqlalchemy中如何做到这一点呢?有什么简单的方法吗?您需要发出相应的SQL指令来实现这一点。例如,演示了在Postgresql上可以使用命令“设置所有延迟的约束”。另一种方法是使用SQLAlchemy来反映所有的约束,然后明确地删除它们,然后重新创建它们-你可以从配方中提出一些想法,这可能会有所帮助。谢谢,这看起来确实是一个可能的方向,尽管我觉得奇怪,这是最简单的方法。如果我找不到更简单的方法,我会使用这种方法。谢谢@zzzeek,我最终使用了你建议的技术,这很好,但是我在sqlalchemy中如何做到这一点呢?有什么简单的方法吗?您需要发出相应的SQL指令来实现这一点。例如,演示了在Postgresql上可以使用命令“设置所有延迟的约束”。另一种方法是使用SQLAlchemy来反映所有的约束,然后明确地删除它们,然后重新创建它们-你可以从配方中提出一些想法,这可能会有所帮助。谢谢,这看起来确实是一个可能的方向,尽管我觉得奇怪,这是最简单的方法。如果我找不到更简单的方法,我会采用这种方法。谢谢@zzzeek,我最终使用了你建议的技术