У меня есть приложение 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:[email protected]:%s/dbname' % server.local_bind_port)
Соединение, похоже, работает, но я не могу обновить свою БД из моих миграций (обновление флеш-памяти), так как я не использую SQLALCHEMY_DATABASE_URI для подключения к моей БД. Есть ли способ сделать обновление db работать с подключением ssh к БД?
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:[email protected]:%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
, но вы Получите эту идею.