SQLAlchemy DB升级和MySQL SSH

时间:2018-05-31 09:05:07

标签: python mysql flask sqlalchemy flask-sqlalchemy

我有一个Flask应用程序需要在我的 init .py文件中使用我的config.py文件中的SSHTunnel连接到远程MysqlDB:

sshtunnel.SSH_TIMEOUT = 5.0
sshtunnel.TUNNEL_TIMEOUT = 5.0

server =  sshtunnel.SSHTunnelForwarder(
    ('ssh.pythonanywhere.com', 22),
    ssh_password="mypassword",
    ssh_username="myusername",
    remote_bind_address=(myname.mysql.pythonanywhere-services.com', 3306))
server.start()

engine = create_engine('mysql+mysqldb://mynameb:dbpassword@127.0.0.1:%s/dbname' % server.local_bind_port)

连接似乎正在起作用,但由于我没有使用SQLALCHEMY_DATABASE_URI连接到我的数据库,因此无法从迁移(刻录数据库升级)升级数据库。是否还有一种方法可以使db升级与DB的ssh连接一起工作?

1 个答案:

答案 0 :(得分:0)

Alembic不必使用数据库URI连接到数据库来运行升级。在alembic\env.py文件中,会出现如下函数:

def run_migrations_online():
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """
    connectable = engine_from_config(
        config.get_section(config.config_ini_section),
        prefix='sqlalchemy.',
        poolclass=pool.NullPool)

    with connectable.connect() as connection:
        context.configure(
            connection=connection,
            target_metadata=target_metadata
        )

        with context.begin_transaction():
            context.run_migrations()

重要的是,当alembic在其上调用connectable时,变量engineconnect()个实例。

因此你可以做这样的事情(这不是经过测试,但我自己做了类似的事情):

def run_migrations_online():
    """Run migrations in 'online' mode.

    In this scenario we need to create an Engine
    and associate a connection with the context.

    """

    sshtunnel.SSH_TIMEOUT = 5.0
    sshtunnel.TUNNEL_TIMEOUT = 5.0

    server =  sshtunnel.SSHTunnelForwarder(
        ('ssh.pythonanywhere.com', 22),
        ssh_password="mypassword",
        ssh_username="myusername",
        remote_bind_address=\
            (myname.mysql.pythonanywhere-services.com', 3306))
    server.start()

    connectable = create_engine(
        'mysql+mysqldb://mynameb:dbpassword@127.0.0.1:%s/dbname' % 
        server.local_bind_port
    )

    with connectable.connect() as connection:
        context.configure(
            connection=connection,
            target_metadata=target_metadata
        )

        with context.begin_transaction():
            context.run_migrations()

理想情况下,您可以将所有连接逻辑放在可以从alembic/env.py和项目中访问的位置,这样您只需定义一次,然后就可以直接导入engine进入env.py,但你明白了。