SQLAlchemy DB обновление и MySQL SSH - PullRequest
0 голосов
/ 31 мая 2018

У меня есть приложение Flask, которое мне нужно подключить к удаленному MysqlDB с помощью SSHTunnel, подобного этому, в моем файле config.py, который я инициализирую в моем файле init .py:

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 для подключения к моей БД.Есть ли еще способ заставить обновление базы данных работать с ssh-подключением к БД?

1 Ответ

0 голосов
/ 01 июня 2018

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()

Все, что имеет значение, это то, что переменная connectable является экземпляром engine, когда alembic вызывает connect() для нее.

Поэтому вы могли бы сделать что-то подобное (это не проверено, но я сам делаю что-то подобное):

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, но вы поняли идею.

...