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