使用automap\u base和alembic迁移/复制数据库

b0zn9rqh  于 2021-06-17  发布在  Mysql
关注(0)|答案(1)|浏览(422)

我有一个数据库 x 在每个表中都填充了一些数据。我想创建该数据库的副本(使用相同的模式和精确的数据)。首先,我创建一个 x 使用自动Map库。

from sqlalchemy.ext.automap import automap_base
from sqlalchemy.orm import Session as s

def name_for_scalar_relationship(base, local_cls, referred_cls, constraint):
    name = referred_cls.__name__.lower() + "_ref"
    return name

Base = automap_base()

# engine, refering to the original database

engine = create_engine("mysql+pymysql://root:password1@localhost:3306/x")

# reflect the tables

Base.prepare(engine, reflect=True, name_for_scalar_relationship=name_for_scalar_relationship)

Router = Base.classes.router

######## check the data in Router table

session = s(engine)
r1 = session.query(Router).all()
for n in r1:
    print(n.name)   #This returns all the router names

从这里得到一些帮助 alembic 升级数据库 y 在不同的地方 mysql+pymysql://anum:Anum-6630@localhost:3306/y .

from sqlalchemy.orm import sessionmaker as sm
from sqlalchemy import create_engine
from alembic import op

# revision identifiers, used by Alembic.

revision = 'fae98f65a6ff'
down_revision = None
branch_labels = None
depends_on = None

def upgrade():
    bind = op.get_bind()
    session = sm(bind=bind)
    Base.metadata.create_all(bind=bind)

    # session._add_bind(session, bind=bind)
    session.add(Router(id=uuid.uuid().bytes, serial="Test1"))
    session.commit()

线路 Base.metadata.create_all(bind=bind) 实际地将所有表(包括适当的fk约束)添加到数据库中 y ,但所有的表都是空的,除了路由器表中的一个条目是我手动添加的。我试过使用create_all(),但效果不太好。有没有办法把所有的数据从 xy 数据库?

ekqde3dh

ekqde3dh1#

由于没有人回答,下面是我执行复制的wild方法:因为表需要按顺序创建(以避免fk约束错误),所以我必须定义一个包含每个表的有序列表
缓慢且不可靠的解决方案:

allTables = ["tableA", 
             "tableB", # <table B points to FK constraint of tableA>
             "tableC", # <table C points to FK constraint of tableB>
             ...]

def copyAllContent():
    global allTables
    s = Session(bind=origEngine)  # session bind to original table
    se = Session(bind=op.get_bind()) # session bind to cloned table (currently empty)
try:
    for table in allTables:
        # print(table)
        rows = s.query(Base.classes._data[table]).all()
        for row in rows:
            local_object = se.merge(row)  #merging both sessions
            se.add(local_object)
            se.commit()
except Exception as e:
    print(e)

上述方法适用于大多数表,但不是所有表。e、 g.table router 存在于原始数据库中,但我仍然在 s.query(Base.classes._data[table]).all() 不存在名为的密钥 router . 我没有足够的时间来找出解决办法。
快速可靠的解决方案:
后来,我从这里找到了另一个快速、安静、可靠的解决方案 mysqldump ```

copy sql dump from x database

mysqldump --column-statistics=0 -P 8000 -h localhost -u root -p --hex-blob x > x_dump.sql

上面的命令行 `mysqldump` 命令创建一个名为 `x_dump.sql` 其中包含重新生成数据库所需的所有必要sql脚本。现在我们需要做的就是将这个sql转储文件应用到另一个数据库 `y` ```

# clone the database contents into y database

mysql -P 3306 -h localhost -u anum -p y < x_dump.sql

这里是做同样的pythonic版本

import subprocess

# copy sql dump from x database - blocking call (use Popen for non-blocking)

print(subprocess.call(["mysqldump", "--column-statistics=0", '-P', '8000', '-h', 'localhost', '-u', '<user>', '-p<password>',
                        '--hex-blob', 'x', '>', 'x_dump.sql'], shell=True))

print("done taking dump.")

# clone the database contents into y database - blocking call

print(subprocess.call(["mysql", '-P', '3306', '-h', 'localhost', '-u', '<user>', '-p<password>',
                        'y', '<', 'x_dump.sql'], shell=True))

print("done cloning the sqlDump.")

相关问题