Steps required to set up the dbt SQL Server Adapter
- data
- 2024-05-09
- 6 minutes to read
- dbt
- sql server
Table of Contents
Introduction
I am currently researching dbt, a data transformation tool that allows you to transform data in your warehouse more effectively. One of the things that is really interesting about it, is that dbt has a set of adapters that allow you to interchange between different database engines.
It is also really easy to get started with local development. There are a few hoops to jump through to get the sql server adapter working with macOS, so I thought I would document them here. Beyond the driver pre-requisites, you can pretty much follow these same steps for Windows.
Adapters?
dbt uses dedicated adapters to connect to different databases. The adapter is responsible for translating dbt’s SQL into the SQL dialect of the database you are using. dbt seems to interchange the words adapters and plugins. Adapters are built as python modules and will be discovered by dbt if installed. There are two types of adapters, trusted and community.
Trusted adapter
The trusted adapters are managed through a Trusted Adapter Program, it suggests that there is a commitment to maintaining the state of the adapter and adhering to a contractual requirement for development, documentation, user experience, and maintenance.
Community adapter
The community adapters are open-source and community maintained, what this does mean is that the adapters might not be fully functional or may have usage inconsistencies.
SQL Server adapter is a community adapter
The SQL Server adapter is a community adapter, so it may not be as complete, or maintained as well as the trusted adapters. Just downloading the quickstart project and running dbt run
I have run into errors in syntax. It’s likely to be that a) the project hasn’t been designed to cater for the sql adapter or b) the adapter isn’t fully functional or probably a combination of both. So whilst I am finding my way with dbt, I will be focusing on a trusted adapter and exploring how to handle the community adapters once I have a bit more knowledge.
Postgres for the win
Whilst I am exploring dbt, I will be using the Postgres adapter. It’s a trusted adapter and I can have it spin up in a docker container locally in a few minutes, meaning I can get on with learning dbt without signing up for any cloud services. You can read about that in this blog post. Nevertheless, here are the issues I encountered getting the SQL Server adapter up and running on macOS and how I fixed them…
Pre-requisites
Docker and SQL Server
First things first, you will need to have SQL Server running locally. I have written about that in this blog post.
Install Microsoft ODBC driver
The dbt SQL adapter requires the Microsoft ODBC Driver 18 for SQL Server
. Windows users can download it using this link. You can install on macOS using homebrew:
brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release
brew update
HOMEBREW_ACCEPT_EULA=Y brew install msodbcsql18 mssql-tools18
Install supporting drivers
From here you should be able to just run pip install dbt-sqlserver
and be good to go. However, there are some issues with the supporting drivers on macOS and they need to be installed first. If you have already run the command, you may have seen an error like:
ImportError: dlopen(/Users/justin/python/dbt/lib/python3.12/site-packages/pyodbc.cpython-312-darwin.so, 0x0002): symbol not found in flat namespace '_SQLAllocHandle'
If you are not interested in the details, run this command, that should do the trick:
pip install --no-binary :all: pyodbc==5.0.1 --force-reinstall
You can now move on to installing the dbt-sqlserver adapter. For those interested in the issues, read on…
Troubleshooting the supporting drivers
So a bit of a rabbit hole here, I started uninstalling unixodbc and pyodbc trying a few suggestions I found online. I did end up causing myself a secondary issue at this point:
ERROR: pip's dependency resolver does not currently take into account all the packages that are installed. This behaviour is the source of the following dependency conflicts.
dbt-sqlserver 1.7.4 requires pyodbc<5.1.0,>=4.0.35, but you have pyodbc 5.1.0 which is incompatible.
By reinstalling pyodbc I installed a version not compatible with dbt-sqlserver, so pip install pyodbc==5.0.1
fixed that however, I still had the original issue. The error message was:
ImportError: dlopen(/Users/justin/python/dbt/lib/python3.12/site-packages/pyodbc.cpython-312-darwin.so, 0x0002): symbol not found in flat namespace '_SQLAllocHandle'
The suggestion is that the package is not compiled properly for ARM as suggested in this stack overflow post and sure enough, using the --no-binary
flag along with the version number fixed the issue. Therefore the command to install the supporting drivers is as follows:
pip install --no-binary :all: pyodbc==5.0.1 --force-reinstall
Install and configure dbt-sqlserver
Just as a summary, the complete set of commands is:
# installs the Microsoft ODBC driver and unixodbc
brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release
brew update
HOMEBREW_ACCEPT_EULA=Y brew install msodbcsql18 mssql-tools18
# installs pyodbc
pip install --no-binary :all: pyodbc==5.0.1 --force-reinstall
# installs dbt adapter
pip install dbt-sqlserver
With everything in place, I just need to set up my profile in the profiles.yml
file. This is the file that dbt uses to connect to your database. Using the container I have talked through in this blog post, my profile would look like this:
quickstart-sql-local:
target: dev
outputs:
dev:
database: db1
driver: ODBC Driver 18 for SQL Server
server: localhost
port: 2022
schema: dbo
type: sqlserver
trust_cert: true
user: justin
password: 'ADB@5XRB7k$$N#!9EUDQ!o808*OPQ6AO*deQ0!P$17U2Lw%iEQ'
I can now run dbt commands against my SQL Server database. If I run dbt seed
in my project directory, dbt will connect to my SQL Server database and run the seed files I have defined. Based on the jaffle-shop sandbox project, here are the tables present in the database:
Want to connect to an Azure SQL Database?
In the above example I am using the sql login that was created by the container, but if using an Azure SQL Database it’s preferable to use Microsoft Entra authentication. There are multiple methods within the scope of Entra which you can see in this help file. To repoint my project to an Azure SQL Database, I would simply create a new profile in the profiles.yml
file:
jaffle_shop_sql_azure:
target: dev
outputs:
dev:
database: jjb-dev-scratch-db
driver: ODBC Driver 18 for SQL Server
server: jjb-dev-sql.database.windows.net
schema: dbo
type: sqlserver
authentication: CLI
I have picked the CLI
authentication method, which is the easiest to set up because I just need to run az login
and pass in my azure credentials, dbt will then be able to authenticate using my credentials (assuming I have access to the database). Running the dbt seed
command will now create the tables in the Azure SQL Database:
To uninstall
To fully uninstall the dbt-sqlserver adapter and the related drivers you would run the following commands in this order to avoid any dependency issues:
brew uninstall mssql-tools18
brew uninstall msodbcsql18
brew uninstall unixodbc
pip uninstall dbt-sqlserver
pip uninstall pyodbc
Wrapping Up
Getting dbt set up with SQL Server on a silicon Mac is a bit of a pain, but once you have the correct drivers installed everything else is pretty straightforward. Because this is a community adapter and I just want to focus on learning dbt, I am going to work with the postgres adapter for now. I will come back to the SQL Server adapter once I have a bit more knowledge.