使用SQLAlchemy,如何将三个表的数据库复制到我本地的MySQL数据库?方法调用的正确顺序是什么?

问题描述 投票:0回答:2

我想从这个在线数据库制作一个精确的副本(迁移): 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?

`

python mysql sql sqlalchemy
2个回答
1
投票

假设这是一个常规的 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 等工具。


0
投票

正如 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 方法来做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.