Connecting Databases and executing SQLs in Spacemacs
Here’s how you can connect to databases and execute SQLs in Spacemacs (Emacs).
Configuration
Prerequisites:
- Ruby
- Go
Make sure these are already installed on your system.
Configuration:
-
Enable
sqllayerAdd
sqlto the existingdotspacemacs-configuration-layerslist in your init file. -
Install external dependencies
-
Syntax Checking: Install the
sqlintgem.gem install sqlint -
Formatting: Install
sqlfmtand move it to your$PATH.brew install sqlfmt sqlfmt -v -
LSP supporting: Use
sqls(Go implementation)-
Install
sqlsgo install github.com/sqls-server/sqls@latestThis installs
sqlsundergo env GOPATH(e.g.,~/go/bin). Check:~/go/bin/sqls --versionEnsure Emacs can find the bin by either adding it to
$PATH:export PATH=$PATH:$HOME/go/binOr set the variable
lsp-sqls-serverto its absolute path:(with-eval-after-load 'lsp-sqls (setq lsp-sqls-server "~/go/bin/sqls")) -
Set the variable
sql-backendto'lsp, and the variablesql-lsp-sqls-workspace-config-pathto'workspaceor'root.(setq-default dotspacemacs-configuration-layers '((sql :variables sql-backend 'lsp sql-lsp-sqls-workspace-config-path 'workspace)))The difference between
'workspaceand'rootdepends on whether you are working in a simple project or a multi-module project (monorepo). For a simple project, they are usually the same. The distinction matters when your project has nested folders.-
'root(Project Root):-
This is the top-level directory of your entire project, usually determined by the version control system (e.g., where the
.git/folder lives). -
Use Case: You want one single configuration file to apply to the entire repository, regardless of which sub-folder you are working in.
-
-
'workspace(LSP Workspace Folder):-
This is the specific directory that lsp-mode considers the “root” for the current server instance. In a monorepo, this is often a subdirectory of the Git root.
-
Use Case: You have a monorepo with multiple distinct services (e.g.,
backend/andfrontend/), and you want a different SQL configuration for each one.
-
-
-
Put
.sqls/config.jsonfiles under those directories, andlsp-sqlswill automatically connect DB when a.sqlsfile is first opened.{ "sqls": { "connections": [ { "driver": "mysql", "dataSourceName": "user1:password1@tcp(localhost:3306)/sample_db" }, { "driver": "sqlite3", "dataSourceName": "/path/to/file.db", "alias": "sqlite-local" } ] } }To add multiple connections of the same driver (e.g., two different SQLite databases or two PostgreSQL environments), you simply add another object to the connections array in your configuration file. Each connection entry is independent, even if they share the same “driver”. You can use the “alias” field to give them unique names.
By default,
sqlsautomatically selects the first connection listed in your connections array in.sqls/config.json. If you open a.sqlfile and do not manually switch connections, the LSP server will attempt to provide completions and run queries against that top-most entry. There is no explicit"default": trueproperty in thesqlsconfiguration schema. To change the default connection, you simply reorder the list in your configuration file. -
Another way to connect DB is through the variable
lsp-sqls-connections.(setq lsp-sqls-connections '(((driver . "mysql") (dataSourceName . "<user>:<password>@tcp(localhost:3306)/<database>")) ((driver . "mssql") (dataSourceName . "Server=localhost;Database=sammy;User Id=yyoncho;Password=hunter2;")) ((driver . "postgresql") (dataSourceName . "host=127.0.0.1 port=5432 user=yyoncho password=123456 dbname=sammy sslmode=disable"))))
-
-
Notes on the difference between sqls and sql-ls
I want to enable and use the sql layer in Spacemacs. I’ve installed
sqls as per the
doc.
But when I opened a .sql file it’s the language server
sql-language-server (sql-ls)
that is installed and started automatically.
Under the lsp-mode
installation directory I find two files related to SQL support:
lsp-sql.el and lsp-sqls.el.
It seems the first one is an implementation using the language server sql-ls
(written in TypeScript) and the second is another implementation using the
language server sqls (written in Go).
How do you use the Go version only? — You can disable sql-ls with:
(add-to-list 'lsp-disabled-clients 'sql-ls)
Connecting DB and Executing SQLs
You can connect to a database by opening an interactive REPL buffer (SQLi) using any of these commands:
sql-show-sqli-buffer(C-c C-z,M-m m b b)sql-product-interactive(C-c TAB)spacemacs/sql-start(M-m m ',M-m m s i)
They ask for the connection parameters from user input and create a new session if there isn’t an existing SQLi session.
Another method is using sql-connect and sql-connection-alist:
-
Set an alist of connection parameters in variable
sql-connection-alist.(setq sql-connection-alist '(("mysql-local" ; Used in the SQLi buffer name (sql-product 'mysql) ; See sql-add-product (sql-server "localhost") (sql-port 3306) (sql-user "root") (sql-password "123456") (sql-database "mybase"))))Connections defined here appear in the submenu SQL->Start… for making new SQLi sessions.
-
Start a SQLi session by calling
sql-connect(M-m m b c), which asks for the above configured connection name.(sql-connect "mysql-local")
Once a connection is created you can execute SQLs in the SQLi buffer directly.
You can also send the SQLs from elsewhere to the SQLi buffer. For example, from
a sql-mode buffer you can send SQLs in the current line or region with
sql-send-line-and-next (C-c C-n) or sql-send-region (C-c C-r) among
others.
The SQLs are sent to the last created SQLi buffer by default. You can change the
associated SQLi buffer for a sql-mode buffer or the globally default SQLi
buffer using sql-set-sqli-buffer.
Commands in sql-mode
-
Change SQL dialect for the current buffer:
spacemacs/sql-highlight(M-m m h k) -
Capitalize keywords in region:
sqlup-capitalize-keywords-in-region(M-m m c) -
Format codes
- in buffer:
sqlfmt-buffer(M-m m = =) - in region:
lsp-format-region(M-m m = r)
- in buffer:
- Connections
- LSP (sqls)
- Show all connection:
lsp-sql-show-connections - Switch to another connection:
lsp-sql-switch-connection
- Show all connection:
- Connect DB in a SQLi buffer
sql-show-sqli-buffer(C-c C-z,M-m m b b)sql-product-interactive(C-c TAB)spacemacs/sql-start(M-m m ‘, M-m m s i)
- LSP (sqls)
-
Databases:
- Show all:
lsp-sql-show-databases - Switch:
lsp-sql-switch-database
- Show all:
-
Tables
- Show all tables in the current database:
sql-list-all(C-c C-l a,M-m m l a)lsp-sql-show-tables,lsp-execute-code-action(M-m m a a)
- Show all fields in a table:
sql-list-table(C-c C-l t,M-m m l t)lsp-describe-thing-at-point(C-.)
- Show all tables in the current database:
-
Switch associated SQLi buffer to another:
sql-set-sqli-buffer,sql-set-sqli-buffer-generally -
Execute SQLs in the current:
- line:
sql-send-line-and-next(C-c C-n)spacemacs/sql-send-line-and-next(M-m m s l)spacemacs/sql-send-line-and-next-and-focus(M-m m s L)
- region:
sql-send-region(C-c C-r)spacemacs/sql-send-region(M-m m s r)spacemacs/sql-send-region-and-focus(M-m m s R)lsp-sql-execute-query
- paragraph:
sql-send-paragraph(C-c C-c)spacemacs/sql-send-paragraph(M-m m s f)spacemacs/sql-send-paragraph-and-focus(M-m m s F)lsp-sql-execute-paragraph
- buffer:
sql-send-buffer(C-c C-b)spacemacs/sql-send-buffer(M-m m s b)spacemacs/sql-send-buffer-and-focus(M-m m s B)lsp-sql-execute-query
- minibuffer:
sql-send-string(C-c C-s)spacemacs/sql-send-string(M-m m s q)spacemacs/sql-send-string-and-focus(M-m m s Q)
- line:
Commands in sql-interactive-mode
- Rename buffer
- by appending a number:
sql-rename-buffer(M-m m b r) - to another name: Pass a
universal-argumentto the above
- by appending a number:
- Save the connection information of the current session to
sql-connection-alistif it wasn’t started with a connection name:sql-save-connection(M-m m b S)
References
- https://emacs-lsp.github.io/lsp-mode/page/lsp-sqls/
- https://www.spacemacs.org/layers/+lang/sql/README.html
- https://github.com/sqls-server/sqls
- help:sql-help
Comments