我想从这个在线数据库制作一个精确的副本(迁移): https://relational.fit.cvut.cz/dataset/ConsumerExpenditures
并将这些表和这些表中的数据复制到我的本地 MySQL 数据库。
我研究了 SQLAlchemy,但由于反射、元数据等的混乱,我对复制这些表的正确调用顺序感到困惑(请参阅代码块的最后部分)。谁能告诉我正确的方法吗?
这是迄今为止我的代码:
` 尝试:
# Read tables from database and copy over to local MySQL
srcEngine = sqlalchemy.create_engine("mariadb+mariadbconnector://guest:[email protected]:3306/ConsumerExpenditures")
conn = srcEngine.connect()
meta = MetaData()
meta.reflect(bind=srcEngine)
meta.tables.keys() # here I see the three tables in this database
# connect to local database
database_uri = 'mysql+pymysql://root:1234@localhost:3306'
localEngine = sqlalchemy.create_engine(database_uri)
try:
with localEngine.connect() as conn_local:
# create ConsumerExpenditures database if not exists else start copying over tables
database = 'ConsumerExpenditures'
result = conn_local.execute(text("CREATE DATABASE IF NOT EXISTS {0} ".format(database)))
# below I am trying to get the metadata from the srcEngine and somehow copy its tables and data over to the localEngine database that was just created. I am sure of the syntax to do this?
meta = MetaData()
messages = Table('EXPENDITURES', meta, autoload=True, autoload_with=srcEngine) # tried to create a table based on the meta data from the source engine but is throwing an error. What is the call(s) I should make to copy it over?
`
假设这是一个常规的 MySql DB 或 MariaDb,根据我的经验(不是 python 的忠实粉丝),当将数据库复制到另一台服务器时,使用 MYSQLDUMP 命令导出,然后使用 MYSQL 命令导入。
导出
mysqldump -u [user] -p [database_name] > [filename].sql
导入/恢复
mysql -u [user] -p [database_name] < [filename].sql
您应该能够使用 Python 使用子进程或系统来执行此操作;- https://docs.python.org/3.6/library/subprocess.html 或者 https://docs.python.org/3.6/library/os.html?highlight=system#os.system
或者使用 PHPMYADMIN 或 MYSQLworkbench 等工具。
正如 Clint 提到的,您可以使用 Python 的
subprocess
模块来执行此操作。这是一个例子:
import subprocess
def dump_remote_database(config):
sql_file_path = "remote_db_dump.sql"
params = [
"mysqldump",
f"--user={config.SOURCE_DB_USER}",
f"--password={config.SOURCE_DB_PASSWORD}",
f"--host={config.SOURCE_DB_HOST}",
f"--result-file={sql_file_path}",
config.SOURCE_DB_NAME,
]
if include_data is True:
params.append("--no-create-info")
# params.append('--ignore-table=crewbuilder.alembic_version')
else:
params.append("--no-data")
result = subprocess.run(params)
我的特殊情况有一些复杂性,我有时还会使用选项
--no-create-info
或 --no-data
,具体取决于我从源数据库中到底需要什么(有时我只需要数据,其他时候只需要表结构)。
同样,要加载数据库,您可以执行以下操作:
import subprocess
def seed_target_database(config):
sql_file_path = "remote_db_dump.sql"
params = [
"mysql",
f"--user={config.TARGET_DB_USER}",
f"--password={config.TARGET_DB_PASSWORD}",
f"--host={config.TARGET_DB_HOST}",
"--protocol=tcp",
config.TARGET_DB_NAME,
]
try:
with open(sql_file_path) as f:
result = subprocess.run(params, stdin=f)
如果您好奇或有兴趣,我的应用程序使用 Flask、Flask-Migrate 和 SQLAlchemy 以及 MySQL 数据库。
我偶然发现了这个问题,因为我正在尝试not使用
mysql
来加载数据,因为它似乎并不在我需要它的所有环境中可用。因此,我正在寻找一种 SQLAlchemy 方法来做到这一点。