#python-3.x #azure-sql-database #pyodbc #openshift-3 #msodbcsql17
#python-3.x #azure-sql-database #pyodbc #openshift-3 #msodbcsql17
Вопрос:
Только при попытке подключиться к моей базе данных Azure из Python 3.7, запущенной в контейнере OpenShift (ИЗ rhel7: последняя версия) Я вижу следующую ошибку:
sqlalchemy.exc.DBAPIError: (pyodbc.Error) ('IM004', "[IM004][unixODBC][Driver Manager]Driver's SQLAllocHandle on SQL_HANDLE_HENV failed (0) (SQLDriverConnect)
Я попробовал точно такой же код в Docker на моем MAC, Windows и RHEL7 Virtualbox, на котором запущен базовый контейнер RHEL7 — он всегда работает! Проблема только в моем контейнере, работающем в OpenShift!
Я проверил, что могу подключиться по telnet к своему серверу Azure DB в 1433 из Openshift.
Я также включил журналы ODBC, но там нет дополнительной информации, кроме указанной выше ошибки.
Что еще я должен проверить?
Вот как я настроил драйвер MSODBC в моем Dockerfile:
RUN curl https://packages.microsoft.com/config/rhel/7/prod.repo > /etc/yum.repos.d/mssql-release.repo amp;amp;
yum remove unixODBC-utf16 unixODBC-utf16-devel amp;amp;
ACCEPT_EULA=Y yum install -y msodbcsql17 amp;amp;
yum install -y unixODBC-devel
И вот код, который выдает ошибку:
внутренние модули.база данных:
pyodbc_connstring_safe = 'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER=' config.settings["DB_HOST"]
';PORT=1433;DATABASE=' config.settings["DB_NAME"] ';UID=' config.usernames["database"]
';PWD={};MARS_Connection=Yes'
if config.settings["debug"]:
print("Using DB connection string: {}".format(pyodbc_connstring_safe.format("SAFE_DB_PASS")))
pyodbc_connstring = pyodbc_connstring_safe.format(config.passwords["database"])
Base = declarative_base()
quoted = urllib.parse.quote_plus(pyodbc_connstring)
def get_engine():
return create_engine('mssql pyodbc:///?odbc_connect={}'.format(quoted), echo=config.settings["debug"], pool_pre_ping=True)
Внутри моего приложения flask (ошибка выдается при вызове ‘has_table’):
@app.route("/baselinedb", methods=["POST"])
def create_db():
from modules.database import Base
engine = database.get_engine()
if not engine.dialect.has_table(engine, database.get_db_object_name("BaselineDefinition"), schema = 'dbo'):
Base.metadata.create_all(engine)
db.session.commit()
return "OK"
Как я упоминал в начале, тот же Dockerfile предоставляет мне рабочий контейнер в Docker либо локально на Mac или Windows, либо внутри виртуальной машины RHEL7.
Спасибо, что посмотрели!
Комментарии:
1. Используете ли вы расширение Flask-SQLAlchemy или расширение Flask-Login для OpenShift? В этом руководстве рассматриваются оба варианта и, возможно, это поможет вам перепроверить конфигурацию в среде OpenShift: blog.openshift.com /…
2. Спасибо @MikeUbezziMSFT, я использую Flask-SQLAlchemy. Я посмотрю на ссылку!
Ответ №1:
unixODBC пытается найти odbc.ini в домашнем каталоге текущего пользователя. Он пытается сделать это, просматривая пользователя в /etc / passwd. Поскольку Openshift использует UID, специфичный для проекта, который не существует в / etc / passwd, пользовательский поиск не будет работать, и соединение не будет выполнено.
Чтобы устранить это, добавьте следующее в файл dockerfile
ADD entrypoint.sh .
RUN chmod 766 /etc/passwd
..
..
ENTRYPOINT entrypoint.sh
И следующее в сценарии точки входа
export $(id)
echo "default:x:$uid:0:user for openshift:/tmp:/bin/bash" >> /etc/passwd
python3.7 app.py
Вышеуказанный файл вставит текущего пользователя в / etc / passwd во время запуска контейнера.
Альтернативным и, вероятно, лучшим подходом может быть использование nss_wrapper:https://cwrap.org/nss_wrapper.html
Комментарии:
1. Очень хороший пример того, как решить эту проблему в вашем образе Docker с помощью nss_wrapper, можно найти здесь: github.com/openshift/jenkins/pull/1024/files
2. @filip-reimer вы знаете, как мы можем сделать это для debian 10? Предоставленное вами решение, похоже, предназначено только для openshift
Ответ №2:
Я столкнулся с той же проблемой при использовании django в Windows. После обновления «клиента SQL Server 2017» до последней версии клиент решает мою проблему. Используйте ссылку ниже для загрузки последнего исправления:https://www.microsoft.com/en-us/download/details.aspx?id=56567