sql

All things SQL and JDBC...
the2bears 2021-02-23T02:15:20.021100Z

Hi, Been awhile since I've used JDBC. I'm having some difficulty getting a connection to a SingleStore (MemSQL)

(def maria-db                                                                                                                                                                                                                                                                              
  {:classname "org.mariadb.jdbc.Driver"                                                                                                                                                                                                                                                    
   :dbname            "db_name"                                                                                                                                                                                                                                                            
   :maximum-pool-size  5                                                                                                                                                                                                                                                                   
   :pool-name          "db-pool"                                                                                                                                                                                                                                                           
   :username           "xxxxx"                                                                                                                                                                                                                                                             
   :password           "yyyyy"                                                                                                                                                                                                                                                             
   :connection-uri           "jdbc:<mariadb://host:3306/db_name?verifyServerCertificate=false&amp;useSSL=true&amp;disableSslHostnameVerification=true%22})|mariadb://host:3306/db_name?verifyServerCertificate=false&amp;useSSL=true&amp;disableSslHostnameVerification=true"})>                                                                                                                                            
  
(j/query maria-db "SELECT * FROM db_name.some_table_name;")                                                                                                                                                                                    

the2bears 2021-02-23T02:15:52.021200Z

Getting this error message: `(conn=41911492) Access denied for user 'williamswaney'@'z.z.z.z' (using password: NO)`

the2bears 2021-02-23T02:18:20.021400Z

So it's not getting the username from the config map, nor the password. I tried them in the URI and this time it seems to accept the user and password, but: `Current charset is UTF-8. If password has been set using other charset, consider using option 'passwordCharacterEncoding'`

the2bears 2021-02-23T02:18:39.021600Z

Anyone tried this, and know the cryptic format? 🙂

seancorfield 2021-02-23T02:22:39.021800Z

@the2bears The intent is that you either provide :connection-uri or you provide other keys and let the Clojure library build the URI for you. You can't provide both.

seancorfield 2021-02-23T02:23:17.022Z

Also, it's :user, not :username (only HikariCP requires :username -- no idea why it is the odd one out).

👍 1
dpsutton 2021-02-23T02:24:23.022500Z

in the connection string, the mysql/maria driver has a bug that they aren't handling things correctly ever since the changes in auth for version 8

seancorfield 2021-02-23T02:24:50.022900Z

I'm a bit puzzled what :maximum-pool-size and :pool-name are meant to be -- those aren't meaningful to clojure.java.jdbc (or next.jdbc) and they won't be valid JDBC properties either with those names.

seancorfield 2021-02-23T02:25:18.023100Z

@dpsutton His connection string does not have credentials in it.

the2bears 2021-02-23T02:25:23.023300Z

Yeah, those are left in from trying both the j/query and a hikari pool 🙂

the2bears 2021-02-23T02:25:30.023500Z

But the :user works

seancorfield 2021-02-23T02:25:46.024Z

Remove :connection-uri and let the library build it for you.

dpsutton 2021-02-23T02:25:55.024300Z

> I tried them in the URI and this time it seems to accept the user and password, but: that's what i was responding to

👍 1
seancorfield 2021-02-23T02:26:59.025200Z

(def maria-db
  {:dbtype "mariadb" :classname "org.mariadb.jdbc.Driver"
   :dbname "db_name"
   :user "xxxxx"
   :password "yyyyy"})

dpsutton 2021-02-23T02:27:10.025400Z

<https://stackoverflow.com/questions/54188309/mariadb-connection-client-access-denied-for-user-using-password-no-on-mysql> is a SO post about the unimplemented part for the maria jdbc driver

👍 1
seancorfield 2021-02-23T02:27:31.025600Z

You only need :classname for clojure.java.jdbc because next.jdbc already knows the mariadb data type.

seancorfield 2021-02-23T02:28:24.025900Z

If you need verifyServerCertificate=false&amp;useSSL=true&amp;disableSslHostnameVerification=true added to the URI that is constructed, pass those in the hash map as well:

:verifyServerCertificate false
   :useSSL true
   :disableSslHostnameVerification true

the2bears 2021-02-23T02:28:43.026100Z

So instead of :connection-uri just use :host, :port, :dbtype (not using next.jdbc yet, but might as well as this is just testing for now)

the2bears 2021-02-23T02:29:22.026300Z

Very cool about the extra options to the URI!

seancorfield 2021-02-23T02:29:34.026500Z

You only need :host and :port if they are non-local/non-standard

seancorfield 2021-02-23T02:30:03.026700Z

(although with c.j.j it may need to be told :port 3306 for mariadb)

Nazral 2021-02-23T02:30:19.027100Z

Hello, I am trying to use jdbc to do some batch insert using jdbc/db-do-commands and a begin end block, but it doesn't work, I am not sure what would be the best approach

seancorfield 2021-02-23T02:30:30.027200Z

So, yeah: dbtype, classname, dbname, host, port, user, password, other options you need.

the2bears 2021-02-23T02:30:30.027400Z

Cool, thanks for the help @seancorfield and @dpsutton. Working with :user and I'll play around with next.jdbc and the other suggestions.

seancorfield 2021-02-23T02:30:52.027900Z

db-do-commands is intended for DDL, not SQL.

seancorfield 2021-02-23T02:32:19.028700Z

@archibald.pontier_clo If you're just getting started with JDBC in Clojure, take note of what the clojure.java.jdbc README says on GitHub: "A low-level Clojure wrapper for JDBC-based access to databases. This project is "Stable" (no longer "Active"). It has effectively been superseded by seancorfield/next.jdbc."

Nazral 2021-02-23T02:33:09.029400Z

I completely missed that, thanks!

seancorfield 2021-02-23T02:33:22.029700Z

Both c.j.j and next.jdbc have specific ways to do batch inserts but they are different. next.jdbc has much better documentation 🙂

seancorfield 2021-02-23T02:34:12.030Z

If you want to insert multiple rows with c.j.j see http://clojure-doc.org/articles/ecosystem/java_jdbc/using_sql.html#inserting-multiple-rows

seancorfield 2021-02-23T02:34:38.030500Z

If you want to insert multiple rows with next.jdbc see https://cljdoc.org/d/seancorfield/next.jdbc/1.1.613/doc/getting-started/friendly-sql-functions#insert-multi

seancorfield 2021-02-23T02:35:35.031600Z

But there are some caveats about batch insertion -- as noted in that doc, and it links you to execute-batch! for large batches.

Nazral 2021-02-23T02:36:10.032300Z

I saw the doc for c.j.j about multiple inserts, but does it update if the row already exists ?

seancorfield 2021-02-23T02:36:32.032800Z

They are inserts so, they just insert.

Nazral 2021-02-23T02:37:01.033800Z

what I am trying to reproduce is a batch INSERT INTO mytable VALUES (...) ON DUPLICATE KEY UPDATE ...

seancorfield 2021-02-23T02:37:27.034300Z

If you want more control, you need to supply the SQL yourself with execute-batch! in next.jdbc.

Nazral 2021-02-23T02:37:54.034600Z

ok, will do that, thank you

seancorfield 2021-02-23T02:37:56.034700Z

What DB are you using?

Nazral 2021-02-23T02:38:28.034900Z

mariadb

seancorfield 2021-02-23T02:39:14.035500Z

Ah, I figured it was MySQL maybe since ON DUPLICATE KEY is not standard SQL.

seancorfield 2021-02-23T02:39:47.036300Z

Which reminds me, I need to add support for that in HoneySQL 2.0 under the :mysql dialect (it already supports all the PostgreSQL upserting stuff).

Nazral 2021-02-23T02:46:10.037200Z

is the difference between execute-batch! and execute! mainly that execute-batch wraps the query into a begin ... end ?

seancorfield 2021-02-23T04:36:57.038200Z

@archibald.pontier_clo No. Did the documentation not make sense to you?

Nazral 2021-02-23T04:38:10.038900Z

yes I got it to works in the meantime, thanks 😛

seancorfield 2021-02-23T04:40:48.040Z

Unfortunately, there's quite a lot of JDBC machinery that you need to be aware of to work effectively with databases -- and every database has its own strange quirks.