xzkostyan / clickhouse-sqlalchemy

ClickHouse dialect for SQLAlchemy
https://clickhouse-sqlalchemy.readthedocs.io
Other
417 stars 120 forks source link

using http mode, connecting database failed when account password ends with @ #313

Open flyly0755 opened 1 month ago

flyly0755 commented 1 month ago

Describe the bug

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.pool import NullPool

chuser = "default"
chpwd = "chpwd123@"  # end with @
chhost = "chhost"
chport = "8123"
dbname = 'db1'
uri = "{}://{}:{}@{}:{}/{}".format('clickhouse', chuser, chpwd, chhost, chport, dbname)
ch_engine = create_engine(uri, echo=False, poolclass=NullPool)
ch_session = sessionmaker(bind=ch_engine)()
ch_session.execute("select 1")  # failed

Raise error clickhouse_sqlalchemy.exceptions.DatabaseException: Orig exception: Code: 516. DB::Exception: default: Authentication failed: password is incorrect or there is no user with such name. (AUTHENTICATION_FAILED) (version xxx)

To Reproduce try code as above, can reproduce this issue 100% Compare with password not end with @, can connect successully. Plus, use tcp mode: uri = "{}://{}:{}@{}:{}/{}".format('clickhouse+native', chuser, chpwd, chhost, 9000, dbname) can also connect successully. Maybe with http mode, password end with @, when processing, cut string wrong when uri like clickhouse://default:chpwd123@@chhost:8123/db1 with 2@

It's possible that password contains @ (like chpwd@123, @chpwd123) exists same problem, I didn't take extra try. Expected behavior Can connect database successfully.

Versions Python: 3.9.11 clickhouse-sqlalchemy: 0.2.3 SQLAlchemy: 1.4.49 SQLAlchemy-Utils: 0.41.1 clickhouse-driver: 0.2.7

iewgnaw commented 1 month ago

if password contains the @ symbol, it needs to be URL-encoded to ensure the URI parser correctly interprets the components of the string. URL encoding converts the @ symbol to %40.

For instance, if the password is pass@word, you should write the connection string as follows:

username:pass%40word@hostname:port/database
flyly0755 commented 1 month ago

if password contains the @ symbol, it needs to be URL-encoded to ensure the URI parser correctly interprets the components of the string. URL encoding converts the @ symbol to %40.

For instance, if the password is pass@word, you should write the connection string as follows:

username:pass%40word@hostname:port/database

Thank you for the solution. But now raise another quesiton, why with tcp mode no need extra convertion, uri showed as below can work.

clickhouse+native://username:pass@word@hostname:port/database