0%

Mac OS X系统Python3连接Mysql

环境

OS: MacOS Sierra 10.12.6
Python: 3.6.5

步骤

python3连接Mysql用得多的两个库分别是PyMySQL和mysqlclient-python,两个库的作者都是同一人。PyMySQL安装起来相对简单,但实际应用中,mysqlclient-python运行速度更快。

升级pip版本,如果不升级系统都会提示你升级的

1
$ pip3 install --upgrade pip

安装PyMySQL

1
2
3
4
5
6
$ pip3 install pymysql

Collecting pymysql
Using cached https://files.pythonhosted.org/packages/32/e8/222d9e1c7821f935d6dba8d4c60b9985124149b35a9f93a84f0b98afc219/PyMySQL-0.8.1-py2.py3-none-any.whl
Installing collected packages: pymysql
Successfully installed pymysql-0.8.1

安装mysqlclient-python

参考官方文档https://github.com/PyMySQL/mysqlclient-python

1
2
$ brew install mysql-connector-c
$ sudo pip3 install mysqlclient

结果报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
The directory '/Users/simon/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/Users/simon/Library/Caches/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting mysqlclient
Downloading https://files.pythonhosted.org/packages/6f/86/bad31f1c1bb0cc99e88ca2adb7cb5c71f7a6540c1bb001480513de76a931/mysqlclient-1.3.12.tar.gz (89kB)
100% |████████████████████████████████| 92kB 13kB/s
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/private/tmp/pip-install-bqcij69j/mysqlclient/setup.py", line 17, in <module>
metadata, options = get_config()
File "/private/tmp/pip-install-bqcij69j/mysqlclient/setup_posix.py", line 54, in get_config
libraries = [dequote(i[2:]) for i in libs if i.startswith('-l')]
File "/private/tmp/pip-install-bqcij69j/mysqlclient/setup_posix.py", line 54, in <listcomp>
libraries = [dequote(i[2:]) for i in libs if i.startswith('-l')]
File "/private/tmp/pip-install-bqcij69j/mysqlclient/setup_posix.py", line 12, in dequote
if s[0] in "\"'" and s[0] == s[-1]:
IndexError: string index out of range

----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/tmp/pip-install-bqcij69j/mysqlclient/

需要说明的一点就是,MySQL Connector/C(6.1.10)在macOS是存在Bug的。

需要修改mysql_config文件

把文件

1
2
3
4
# on macOS, on or about line 112:
# Create options
libs="-L$pkglibdir"
libs="$libs -l "

修改为
1
2
3
# Create options 
libs="-L$pkglibdir"
libs="$libs -lmysqlclient -lssl -lcrypto"

再次安装,继续报错:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
The directory '/Users/simon/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/Users/simon/Library/Caches/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting mysqlclient
Downloading https://files.pythonhosted.org/packages/6f/86/bad31f1c1bb0cc99e88ca2adb7cb5c71f7a6540c1bb001480513de76a931/mysqlclient-1.3.12.tar.gz (89kB)
100% |████████████████████████████████| 92kB 122kB/s
Installing collected packages: mysqlclient
Running setup.py install for mysqlclient ... error
Complete output from command /Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/private/tmp/pip-install-l1_o52yl/mysqlclient/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /private/tmp/pip-record-zkfu3qn7/install-record.txt --single-version-externally-managed --compile:
running install
running build
running build_py
creating build
creating build/lib.macosx-10.9-x86_64-3.6
copying _mysql_exceptions.py -> build/lib.macosx-10.9-x86_64-3.6
creating build/lib.macosx-10.9-x86_64-3.6/MySQLdb
copying MySQLdb/__init__.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb
copying MySQLdb/compat.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb
copying MySQLdb/connections.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb
copying MySQLdb/converters.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb
copying MySQLdb/cursors.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb
copying MySQLdb/release.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb
copying MySQLdb/times.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb
creating build/lib.macosx-10.9-x86_64-3.6/MySQLdb/constants
copying MySQLdb/constants/__init__.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb/constants
copying MySQLdb/constants/CLIENT.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb/constants
copying MySQLdb/constants/CR.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb/constants
copying MySQLdb/constants/ER.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb/constants
copying MySQLdb/constants/FIELD_TYPE.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb/constants
copying MySQLdb/constants/FLAG.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb/constants
copying MySQLdb/constants/REFRESH.py -> build/lib.macosx-10.9-x86_64-3.6/MySQLdb/constants
running build_ext
building '_mysql' extension
creating build/temp.macosx-10.9-x86_64-3.6
gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -arch x86_64 -g -Dversion_info=(1,3,12,'final',0) -D__version__=1.3.12 -I/usr/local/Cellar/mysql-connector-c/6.1.10/include -I/Library/Frameworks/Python.framework/Versions/3.6/include/python3.6m -c _mysql.c -o build/temp.macosx-10.9-x86_64-3.6/_mysql.o
gcc -bundle -undefined dynamic_lookup -arch x86_64 -g build/temp.macosx-10.9-x86_64-3.6/_mysql.o -L/usr/local/Cellar/mysql-connector-c/6.1.10/lib -lmysqlclient -lssl -lcrypto -o build/lib.macosx-10.9-x86_64-3.6/_mysql.cpython-36m-darwin.so
ld: library not found for -lssl
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: command 'gcc' failed with exit status 1

----------------------------------------
Command "/Library/Frameworks/Python.framework/Versions/3.6/bin/python3.6 -u -c "import setuptools, tokenize;__file__='/private/tmp/pip-install-l1_o52yl/mysqlclient/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /private/tmp/pip-record-zkfu3qn7/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /private/tmp/pip-install-l1_o52yl/mysqlclient/

很显然,系统提示:ld: library not found for -lssl。作者也告诉了这个错误的解决办法,办法就是brew info openssl,说了相当于没说。

1
2
3
4
5
6
$ brew info openssl

...
For compilers to find this software you may need to set:
LDFLAGS: -L/usr/local/opt/openssl/lib
CPPFLAGS: -I/usr/local/opt/openssl/include

看明白了吗?在编译时,需要加入LDFLAGS这个参数。

最后,我们执行

1
2
3
4
5
6
7
8
9
10
$ sudo LDFLAGS=-L/usr/local/opt/openssl/lib pip3 install mysqlclient

The directory '/Users/simon/Library/Caches/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
The directory '/Users/simon/Library/Caches/pip' or its parent directory is not owned by the current user and caching wheels has been disabled. check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
Collecting mysqlclient
Downloading https://files.pythonhosted.org/packages/6f/86/bad31f1c1bb0cc99e88ca2adb7cb5c71f7a6540c1bb001480513de76a931/mysqlclient-1.3.12.tar.gz (89kB)
100% |████████████████████████████████| 92kB 40kB/s
Installing collected packages: mysqlclient
Running setup.py install for mysqlclient ... done
Successfully installed mysqlclient-1.3.12

mysqlclient安装成功。