简体   繁体   English

如何将 mysql 默认文件 (my.cnf) 与 sqlalchemy 一起使用?

[英]how to use mysql defaults file (my.cnf) with sqlalchemy?

I'd like to have sqlalchemy get the hostname, username, and password for the mysql database it's connecting to.我想让 sqlalchemy 获取它所连接的 mysql 数据库的主机名、用户名和密码。

The documentation says mysql schemas are specified as such:文档说 mysql 模式是这样指定的:

mysql_db = create_engine('mysql://scott:tiger@localhost/foo')

Is it possible to instead source a mysql defaults file such as /etc/my.cnf and get the login details from there?是否可以改为获取 mysql 默认文件(例如 /etc/my.cnf)并从那里获取登录详细信息? I'd like to avoid embedding the username/password in my code.我想避免在我的代码中嵌入用户名/密码。

Here is a result that was found on the sqlalchemy mailing list, posted by Tom H: 以下是在Tomlal发布的sqlalchemy邮件列表中找到的结果:

http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg11241.html http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg11241.html

from sqlalchemy.engine.url import URL

myDB = URL(drivername='mysql', host='localhost',
    database='my_database_name',
    query={ 'read_default_file' : '/path/to/.my.cnf' }
)
engine = create_engine(name_or_url=myDB)
# use the engine as usual, no password needed in your code file :)

If you want to use MySQLdb you could parse the ini file with ConfigParser: 如果你想使用MySQLdb,你可以使用ConfigParser解析ini文件:

sql_ini_fileparser = ConfigParser.RawConfigParser()
sql_ini_fileparser.read('example.cfg')
user = sql_ini_fileparser.get('client', 'user')
password = sql_ini_fileparser.get('client', 'password')

This is an old question, but the accepted answer still forces you to include the hostname as a string. 这是一个老问题,但接受的答案仍然强制您将主机名包含为字符串。 I was looking for a solution that reads the my.cnf file and gets the hostname from there as well. 我一直在寻找一个能够读取my.cnf文件并从中获取主机名的解决方案。

The first thing I found was this page, and the suggestion to build the URL using the query={'read_default_file': 'my.cnf'} keyword. 我找到的第一件事就是这个页面,以及使用query={'read_default_file': 'my.cnf'}关键字构建URL的建议。 The following are all equivalent to his answer, and they all require you to pass in the hostname explicitly, but at least you can get passwords, ports, charset, and other things from the my.cnf file 以下都等同于他的回答,它们都要求你明确传递主机名,但至少你可以从my.cnf文件中获取密码,端口,字符集和其他东西

engine = create_engine('mysql+pymysql://hostname', connect_args={'read_default_file': 'mu.cnf'})
engine = create_engine('mysql+pymysql://hostname?read_default_file=my.cnf')

After reading much of the source code, I believe there is no possible way to get a sqlalchemy engine without passing the hostname into create_engine somehow. 在阅读了大部分源代码之后,我相信没有办法在不以某种方式将主机名传递给create_engine的情况下获取sqlalchemy引擎。

So somehow you have to get the hostname from somewhere else. 所以不知何故,你必须从其他地方获取主机名。 The simplest options for this are to use an environment variable ie host=os.getenv('DATABASE_URI') or to parse a config file using the configparser library like karlo suggested. 最简单的选择是使用环境变量,即host=os.getenv('DATABASE_URI')或者使用像karlo建议的configparser库来解析配置文件。 I prefer the config file because then you don't have to inject usernames and passwords into environment variables - here's roughly how pymysql parses the file in the source code for pymysql.connections.Connection 我比较喜欢的配置文件,因为你没有注入用户名和密码进入环境变量-这里的大致pymysql如何解析该文件中的源代码pymysql.connections.Connection

from configparser import Parser

read_default_group = 'client' # replace this if you're super special
read_default_file = '/etc/my.cnf' # replace this with the path you want to use

cfg = Parser()
cfg.read(defaults_file) 

def _config(key, arg=None):
    try:
        return cfg.get(read_default_group, key)
    except Exception:
        return arg

user = _config("user")
password = _config("password")
host = _config("host")
database = _config("database")
port = int(_config("port", 3306))
charset = _config("charset", "utf8mb4")
engine = create_engine(f'mysql+pymysql://{user}:{password}@{host}:{port}/{database}?charset={charset}')

I know this is an old thread, but the solutions mentioned above would not work for me when attempting to do this as I was connecting via a socket in the cnf file.我知道这是一个旧线程,但是当我尝试通过 cnf 文件中的套接字连接时,上面提到的解决方案对我不起作用。

Instead, I have done the following which works:相反,我做了以下有效的事情:

First off I parse the cnf file to get the username and password.首先,我解析 cnf 文件以获取用户名和密码。

CnfFile = open('/directory/.MyCnfFile.cnf', 'r')
for Line in CnfFile:
    if Line.startswith("user"):
        User = Line.lstrip("user=")
        User = User.rstrip("\n")
    if Line.startswith("password"):
        Password = Line.lstrip("password=")
        Password = Password.rstrip("\n")

I then create the engine using the socket.然后我使用套接字创建引擎。

engine = create_engine("mysql+pymysql://"+User+":"+Password+"@localhost?unix_socket=/var/run/mysqld/mysqld-socket.sock")

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM