gpt4 book ai didi

python - 使用 Python 转储 PostgreSQL 数据库模式

转载 作者:行者123 更新时间:2023-11-29 12:56:59 25 4
gpt4 key购买 nike

我正在寻找一种使用 Python 转储 PostgreSQL 数据库模式的方法。理想情况下,结果将是 .sql 转储或任何其他格式,SQLAlchemy 稍后可以使用该格式从该模式创建新数据库。

我用 SQLAlchemy 的 MetaData class 做了这个实验:

from sqlalchemy import MetaData, create_engine

engine = create_engine(source_database_url)
test_engine = create_engine(test_database_url)
metadata = MetaData()
metadata.reflect(engine)
metadata.create_all(test_engine)

除了导出模式供以后使用外,这完全符合我的要求。因此,考虑到 SQLAlchemy 可以成功地反射(reflect)一个模式并基于它创建另一个表,我希望有一种方法可以在此过程中以编程方式导出它。

我知道我可以从代码中调用 pg_dumppg_restore 但我想避免外部依赖和随之而来的麻烦。

有没有办法用 SQLAlchemy 或其他 Python 库实现这一点?

最佳答案

进一步挖掘后,我发现了这个 helpful section from SQLAlchemy docs .因此,从该代码片段开始,我创建了以下类:

import io
from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import sessionmaker

class SchemaDump(object):
def __init__(self, db_url, schema_file_path):
self.db_url = db_url
self.schema_file_path = schema_file_path
self.buf = io.BytesIO()

def dump_shema(self):
engine = create_engine(self.db_url)
metadata = MetaData()
metadata.reflect(engine)

def dump(sql, *multiparams, **params):
f = sql.compile(dialect=engine.dialect)
self.buf.write(str(f).encode('utf-8'))
self.buf.write(b';\n')

new_engine = create_engine(self.db_url, strategy='mock', executor=dump)
metadata.create_all(new_engine, checkfirst=True)

with io.open(self.schema_file_path, 'wb+') as schema:
schema.write(self.buf.getvalue())

这仍然很粗略,但主要思想是在 buf 中捕获 sql.compile(dialect=engine.dialect) 返回的原始 SQL 语句并写入它们到文件。

我写了一个同样粗略的类来从上面类创建的 .sql 转储中恢复数据库:

import io
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

class RestoreSchema(object):
def __init__(self, db_url, schema_file_path):
self.db_url = db_url
self.schema_file_path = schema_file_path

def restore_schema(self):
raw_schema = ''
with io.open(self.schema_file_path) as sql_schema:
raw_schema = sql_schema.read()
engine = create_engine(self.db_url)
Session = sessionmaker(bind=engine)
session = Session()
conn = engine.connect()
transaction = conn.begin()
try:
conn.execute(raw_schema)
transaction.commit()
except Exception as e:
transaction.rollback()
raise e
finally:
session.close()

你仍然需要担心表是否已经存在等问题,但效果与我问题中的代码片段完全相同。

关于python - 使用 Python 转储 PostgreSQL 数据库模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40619434/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com