シリアライザーのダンプとロードを使用して、sqlalchemy インポート/エクスポート スクリプトを作成しています。エクスポートは機能しますが、主に外部キーの問題が原因で、インポートに問題があります。依存関係に基づいてソートされたテーブルのリストを取得するために sorted_tables を使用しています。これにより、クロステーブルの外部キーの問題が発生しないようになりますが、内部外部キー (それ自体を指すテーブル) を処理するのに似たものがありますか?
私は基本的に2つの可能な解決策について考えています:
- 依存関係に基づいて行を並べ替える方法を見つける
- すべての制約を無効にする -> データを挿入する -> すべての制約を再度有効にする
しかし、これを適切に行う方法がわかりません...
テーブルの例:
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)