Mac M1 ARM64环境Elixir/Erlang调用ODBC加载Snowflake驱动失败
ARM64架构Mac M1设备Elixir应用加载Snowflake ODBC驱动问题
问题背景
相同Elixir应用在x86架构下可正常加载Snowflake驱动运行,迁移到ARM64架构的Mac M1设备后加载失败,经测试isql命令可正常连接Snowflake,但iodbctest测试和Elixir应用测试用例均运行失败。
已安装依赖
- unixodbc
- 带ODBC支持的Erlang 24.1.2
- Snowflake驱动
- iODBC
- ODBC manager & iODBC manager
ODBC配置详情
基础配置信息
➜ sandbox odbcinst -j unixODBC 2.3.9 DRIVERS............: /usr/local/etc/odbcinst.ini SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources USER DATA SOURCES..: /Users/or/.odbc.ini SQLULEN Size.......: 8 SQLLEN Size........: 8 SQLSETPOSIROW Size.: 8
odbcinst.ini配置
➜ sandbox cat /usr/local/etc/odbcinst.ini [ODBC Drivers] SnowflakeDSIIDriver=Installed [SnowflakeDSIIDriver] APILevel=1 ConnectFunctions=YYY Description=Snowflake DSII Driver=/opt/snowflake/snowflakeodbc/lib/universal/libSnowflake.dylib DriverODBCVer=03.52 SQLLevel=1 ODBCInstLib=/usr/local/iODBC/lib/libiodbcinst.dylib
Snowflake驱动配置
➜ sandbox cat /opt/snowflake/snowflakeodbc/lib/universal/simba.snowflake.ini [Driver] ANSIENCODING=UTF-8 DriverManagerEncoding=UTF-32 DriverLocale=en-US ErrorMessagesPath=/opt/snowflake/snowflakeodbc/ErrorMessages LogLevel=0 LogPath= CURLVerboseMode=false CABundleFile=/opt/snowflake/snowflakeodbc/lib/universal/cacert.pem ODBCInstLib=libodbcinst.dylib
odbc.ini数据源配置
➜ sandbox cat /usr/local/etc/odbc.ini [ODBC Data Sources] SNOWFLAKE_ODBC = SnowflakeDSIIDriver [SNOWFLAKE_ODBC] Driver = /opt/snowflake/snowflakeodbc/lib/universal/libSnowflake.dylib Description = Internal Snowflake uid = <> server = MY_SERVER database = <> schema = <> warehouse = <> role = MY_ROLE tracing = 6
数据源查询结果
➜ sandbox odbcinst -s -q [SNOWFLAKE_ODBC]
连接测试结果
isql连接(成功)
➜ sandbox isql -v SNOWFLAKE_ODBC <USERNAME> <PASSWORD> +---------------------------------------+ | Connected! | | | | sql-statement | | help [tablename] | | quit | | | +---------------------------------------+ SQL>
iodbctest连接(失败)
➜ sandbox /usr/local/iODBC/bin/iodbctest iODBC Demonstration program This program shows an interactive SQL processor Driver Manager: 03.52.1521.0607 Enter ODBC connect string (? shows list): DSN | Driver ------------------------------------------------------------------------------ SnowflakeDSII | Snowflake Enter ODBC connect string (? shows list): SnowflakeDSII 1: SQLDriverConnect = [iODBC][Driver Manager]dlopen(/opt/snowflake/snowflakeodbc/lib/universal/libSnowflake.dylib, 6): no suitable image found. Did find: /opt/snowflake/snowflakeodbc/lib/universal/libSnowflake.dylib: no matching architecture in universal wrapper /opt/snowfl (0) SQLSTATE=00000 2: SQLDriverConnect = [iODBC][Driver Manager]Specified driver could not be loaded (0) SQLSTATE=IM003
Elixir测试用例失败详情
测试代码
defmodule Sandbox.OdbcTest do use Sandbox.OdbcCase test "test odbc" do conn_str = 'dsn=SnowflakeDSII' IO.inspect :odbc.connect(conn_str, []) end end
备用连接字符串尝试
conn_str = 'driver=/opt/snowflake/snowflakeodbc/lib/universal/libSnowflake.dylib;server=<SERVER>;uid=<USERNAME>;pwd=<PASSWORD>;role=<ROLE>;warehouse=TEST_WH;'
测试报错输出
➜ sandbox mix test test/odbc_test.exs true 'driver=/opt/snowflake/snowflakeodbc/lib/universal/libSnowflake.dylib;<MY_DSN>' {:error, '[unixODBC][Driver Manager]Can\'t open lib \'/opt/snowflake/snowflakeodbc/lib/universal/libSnowflake.dylib\' : file not found SQLSTATE IS: 01000 Connection to database failed.'} . Finished in 0.05 seconds (0.00s async, 0.05s sync) 1 test, 0 failures Randomized with seed 529170
根因说明
Snowflake官方ODBC驱动当前未提供原生ARM64架构的二进制包,isql可正常连接是因为其运行在Rosetta 2转译的x86模式下,而M1设备上原生编译的Erlang/Elixir运行在ARM64架构下,无法加载仅支持x86架构的驱动二进制文件。
可行解决方案
- 方案1:使用Rosetta 2模式运行整套技术栈
右键点击终端应用,选择「显示简介」,勾选「使用Rosetta打开」,在此终端下重装Homebrew、Erlang、Elixir及所有项目依赖,运行Elixir应用即可兼容x86架构的Snowflake ODBC驱动,该方案改动最小,无需调整现有驱动配置。 - 方案2:替换为非ODBC的Snowflake连接器
放弃系统级ODBC驱动依赖,改用Elixir生态中基于HTTP API实现的原生Snowflake客户端,完全规避跨架构适配问题。 - 方案3:使用Docker容器运行应用
将应用打包到x86架构的Linux容器中,在M1设备上通过Docker的转译层运行,可直接复用x86架构下的所有依赖配置,无需修改业务代码。
内容的提问来源于stack exchange,提问作者ole
相关产品推荐
相关产品推荐

