Using quoted_name:
Represent a SQL identifier combined with quoting preferences.
quoted_name is a Python unicode/str subclass which represents a
particular identifier name along with a quote flag. This quote flag,
when set to True or False, overrides automatic quoting behavior for
this identifier in order to either unconditionally quote or to not
quote the name. If left at its default of None, quoting behavior is
applied to the identifier on a per-backend basis based on an
examination of the token itself.
Here is how I was able to get it to work:
from sqlalchemy.sql import text, quoted_name
DATABASE_USER = "your_user_here"
DATABASE_USER_PASSWORD = "your_password"
create_user_sql = text(f"CREATE USER {quoted_name(DATABASE_USER, False)} WITH PASSWORD :database_password")\
.bindparams( # You can remove this line if you don't want to test
database_password=DATABASE_USER_PASSWORD. # You can remove this line if you don't want to test
)\ # You can remove this line if you don't want to test
.compile(compile_kwargs={"literal_binds": True}) # You can remove this line if you don't want to test
print(str(create_user_sql)) # You can remove this line if you don't want to test
Results in the following being executed:
CREATE USER your_user_here WITH PASSWORD 'your_password'
You can remove the .bindparams() and .compile() and just pass the parameter(s) to connection.execute(create_user_sql, database_password=DATABASE_USER_PASSWORD) which looks cleaner, the code above is just a proof of concept.
sql = f"CREATE USER quote_ident('{username}') WITH PASSWORD :passwd'it is sql injection safe an easy readable combining f-strings with parametrized queries.