mysqlclient MacOS 使用报错 NameError: name ‘_mysql’ is not defined

在MacOS环境下,使用django链接mysql数据库时遇到'NameError: name '_mysql' is not defined'的问题。报错原因是系统找不到_mysql库。解决方法是通过find命令找到mysqlclient库的路径,并将其添加到dylib的动态库查找路径中,设置环境变量后重启服务即可正常连接。
部署运行你感兴趣的模型镜像

背景

最近使用 django 作为一个服务的后台,在使用 mysqlclient 链接 mysql 数据库时发生一个奇怪的报错 NameError: name ‘_mysql’ is not defined

下面是具体报错信息

INFO] 2021-04-07 02:27:57,613 Watching for file changes with StatReloader
Exception in thread django-main-thread:
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/MySQLdb/__init__.py", line 18, in <module>
    from . import _mysql
ImportError: dlopen(/usr/local/lib/python3.7/site-packages/MySQLdb/_mysql.cpython-37m-darwin.so, 2): Library not loaded: @rpath/libmysqlclient.21.dylib
  Referenced from: /usr/local/lib/python3.7/site-packages/MySQLdb/_mysql.cpython-37m-darwin.so
  Reason: image not found

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 926, in _bootstrap_inner
    self.run()
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/utils/autoreload.py", line 53, in wrapper
    fn(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/core/management/commands/runserver.py", line 110, in inner_run
    autoreload.raise_last_exception()
  File "/usr/local/lib/python3.7/site-packages/django/utils/autoreload.py", line 76, in raise_last_exception
    raise _exception[1]
  File "/usr/local/lib/python3.7/site-packages/django/core/management/__init__.py", line 357, in execute
    autoreload.check_errors(django.setup)()
  File "/usr/local/lib/python3.7/site-packages/django/utils/autoreload.py", line 53, in wrapper
    fn(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/__init__.py", line 24, in setup
    apps.populate(settings.INSTALLED_APPS)
  File "/usr/local/lib/python3.7/site-packages/django/apps/registry.py", line 114, in populate
    app_config.import_models()
  File "/usr/local/lib/python3.7/site-packages/django/apps/config.py", line 211, in import_models
    self.models_module = import_module(models_module_name)
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1006, in _gcd_import
  File "<frozen importlib._bootstrap>", line 983, in _find_and_load
  File "<frozen importlib._bootstrap>", line 967, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 677, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/usr/local/lib/python3.7/site-packages/django/contrib/auth/models.py", line 2, in <module>
    from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager
  File "/usr/local/lib/python3.7/site-packages/django/contrib/auth/base_user.py", line 48, in <module>
    class AbstractBaseUser(models.Model):
  File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 122, in __new__
    new_class.add_to_class('_meta', Options(meta, app_label))
  File "/usr/local/lib/python3.7/site-packages/django/db/models/base.py", line 326, in add_to_class
    value.contribute_to_class(cls, name)
  File "/usr/local/lib/python3.7/site-packages/django/db/models/options.py", line 206, in contribute_to_class
    self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
  File "/usr/local/lib/python3.7/site-packages/django/db/__init__.py", line 28, in __getattr__
    return getattr(connections[DEFAULT_DB_ALIAS], item)
  File "/usr/local/lib/python3.7/site-packages/django/db/utils.py", line 214, in __getitem__
    backend = load_backend(db['ENGINE'])
  File "/usr/local/lib/python3.7/site-packages/django/db/utils.py", line 111, in load_backend
    return import_module('%s.base' % backend_name)
  File "/usr/local/Cellar/python/3.7.4_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "/usr/local/lib/python3.7/site-packages/django/db/backends/mysql/base.py", line 15, in <module>
    import MySQLdb as Database
  File "/usr/local/lib/python3.7/site-packages/MySQLdb/__init__.py", line 24, in <module>
    version_info, _mysql.version_info, _mysql.__file__
NameError: name '_mysql' is not defined

其中最关键的报错信息:Library not loaded: @rpath/libmysqlclient.21.dylib ,没有加载 libmysqlclient.21.dylib 这个库,通过 find 命令本机查找 libmysqlclient.21.dylib 位置(每个人电脑上 mysql 安装路径不同,根据具体情况具体分析)。
find / -name libmysqlclient.21.dylib

在这里插入图片描述

解决方案

只需要将找到的 libmysqlclient.21.dylib 路径添加到 LD_LIBRARY_PATH (动态库查找路径)即可,添加环境变量

export LD_LIBRARY_PATH=/usr/local/mysql-8.0.18-macos10.14-x86_64/lib

运行服务即可

python manage.py runserver

参考

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

/home/zbt/S/sylar/sylar/db/mysql.h:120:9: error: ‘my_bool’ does not name a type; did you mean ‘bool’? 120 | my_bool is_null; | ^~~~~~~ | bool /home/zbt/S/sylar/sylar/db/mysql.h:121:9: error: ‘my_bool’ does not name a type; did you mean ‘bool’? 121 | my_bool error; | ^~~~~~~ | bool /home/zbt/S/sylar/sylar/db/mysql.cc: In static member function ‘static sylar::MySQLStmtRes::ptr sylar::MySQLStmtRes::Create(std::shared_ptr<sylar::MySQLStmt>)’: /home/zbt/S/sylar/sylar/db/mysql.cc:660:50: error: ‘__gnu_cxx::__alloc_traits<std::allocator<sylar::MySQLStmtRes::Data>, sylar::MySQLStmtRes::Data>::value_type’ {aka ‘struct sylar::MySQLStmtRes::Data’} has no member named ‘is_null’ 660 | rt->m_binds[i].is_null = &rt->m_datas[i].is_null; | ^~~~~~~ /home/zbt/S/sylar/sylar/db/mysql.cc:661:48: error: ‘__gnu_cxx::__alloc_traits<std::allocator<sylar::MySQLStmtRes::Data>, sylar::MySQLStmtRes::Data>::value_type’ {aka ‘struct sylar::MySQLStmtRes::Data’} has no member named ‘error’ 661 | rt->m_binds[i].error = &rt->m_datas[i].error; | ^~~~~ /home/zbt/S/sylar/sylar/db/mysql.cc: In member function ‘virtual bool sylar::MySQLStmtRes::isNull(int)’: /home/zbt/S/sylar/sylar/db/mysql.cc:700:25: error: ‘__gnu_cxx::__alloc_traits<std::allocator<sylar::MySQLStmtRes::Data>, sylar::MySQLStmtRes::Data>::value_type’ {aka ‘struct sylar::MySQLStmtRes::Data’} has no member named ‘is_null’ 700 | return m_datas[idx].is_null; | ^~~~~~~ /home/zbt/S/sylar/sylar/db/mysql.cc: In constructor ‘sylar::MySQLStmtRes::Data::Data()’: /home/zbt/S/sylar/sylar/db/mysql.cc:766:6: error: class ‘sylar::MySQLStmtRes::Data’ does not have any field named ‘is_null’ 766 | :is_null(0) | ^~~~~~~ /home/zbt/S/sylar/sylar/db/mysql.cc:767:6: error: class ‘sylar::MySQLStmtRes::Data’ does not have any field named ‘error’ 767 | ,error(0) | ^~~~~ make[2]: *** [CMakeFiles/sylar.dir/build.make:137: CMakeFiles/sylar.dir/sylar/db/mysql.cc.o] Error 1 make[2]: Leaving directory '/home/zbt/S/sylar' make[1]: *** [CMakeFiles/Makefile2:248: CMakeFiles/sylar.dir/all] Error 2 make[1]: Leaving directory '/home/zbt/S/sylar' make: *** [Makefile:87: all] Error 2
07-22
<think>我们正在处理一个关于C++项目sylar在编译时遇到MySQL相关错误的问题。错误信息包括: 1. 'my_bool'未声明 2. 某些结构体成员如'is_null'和'error'不存在 根据引用[1]中的CMakeLists.txt配置,项目使用MySQL库(通过`find_library(YAMLCPP yaml-cpp)`,但这里可能是笔误,因为yaml-cpp是YAML解析库,而MySQL库通常需要另外的查找)。实际上,用户的问题是关于MySQL的,所以我们需要确保CMake正确找到了MySQL库并包含了正确的头文件。 ### 问题分析 1. **'my_bool'未声明**:在较新版本的MySQL Connector/C(如8.0以上)中,`my_bool`类型已被弃用,取而代之的是`bool`类型或`mysql_bool`(具体取决于版本)。如果项目使用的是旧版本的MySQL头文件,而编译时链接的是新版本的库,或者反之,则可能出现这种问题。 2. **结构体成员不存在**:错误提示某些结构体成员(如`is_null`和`error`)不存在,这可能是由于MySQL数据结构的版本变化导致的。在MySQL的预处理语句(MYSQL_STMT)中,绑定参数时使用的结构体`MYSQL_BIND`在旧版本中有`is_null`和`error`成员,但在新版本中可能有所变化。 ### 解决方案 #### 步骤1:检查MySQL头文件版本 首先,确认系统安装的MySQL Connector/C版本。在Ubuntu/Debian上,可以通过以下命令查看: ```bash dpkg -l | grep libmysqlclient ``` 在CentOS/RHEL上: ```bash rpm -qa | grep mysql-connector-c ``` #### 步骤2:调整代码以适应MySQL版本变化 根据MySQL版本,我们需要修改sylar项目中MySQL相关的代码。 - **对于`my_bool`未声明的问题**: 在MySQL 8.0中,`my_bool`已被移除。我们可以通过条件编译来兼容不同版本: ```cpp #if MYSQL_VERSION_ID >= 80000 typedef bool my_bool; #else typedef char my_bool; #endif ``` 或者,在包含MySQL头文件之前定义`MY_BOOL_DEFINED`(如果旧版本的头文件已经定义了`my_bool`,则无需重复定义)。 - **对于结构体成员不存在的问题**: 在MySQL 8.0中,`MYSQL_BIND`结构体的`is_null`和`error`成员被替换为指向布尔值的指针(`is_null`变为`is_null_value`,`error`变为`error_value`)。因此,我们需要根据版本调整代码: ```cpp #if MYSQL_VERSION_ID >= 80000 bind[i].is_null = &is_null; bind[i].error = &error; #else bind[i].is_null = is_null; bind[i].error = error; #endif ``` 注意:在旧版本中,`is_null`和`error`是`my_bool*`类型,而在新版本中,它们是`bool*`类型。同时,在旧版本中,我们直接赋值指针,而在新版本中,我们同样赋值指针(但类型不同)。因此,我们需要定义两个变量: ```cpp #if MYSQL_VERSION_ID >= 80000 bool is_null = false; bool error = false; #else my_bool is_null = false; my_bool error = false; #endif ``` #### 步骤3:修改CMakeLists.txt以正确查找MySQL库 在引用[1]的CMakeLists.txt中,我们并没有看到查找MySQL库的语句。因此,我们需要添加查找MySQL库和头文件的指令。在CMakeLists.txt中添加: ```cmake # 查找MySQL的包含路径和库 find_path(MYSQL_INCLUDE_DIR mysql.h PATH_SUFFIXES mysql PATHS /usr/local/mysql/include /usr/include/mysql /usr/local/include/mysql /opt/mysql/include) find_library(MYSQL_LIBRARY NAMES mysqlclient PATHS /usr/local/mysql/lib /usr/lib/mysql /usr/local/lib/mysql /opt/mysql/lib) if (MYSQL_INCLUDE_DIR AND MYSQL_LIBRARY) include_directories(${MYSQL_INCLUDE_DIR}) link_directories(${MYSQL_LIBRARY}) message(STATUS "Found MySQL: ${MYSQL_LIBRARY}") else() message(FATAL_ERROR "MySQL not found") endif() ``` 然后,在链接可执行文件时,将MySQL库链接进去: ```cmake target_link_libraries(test_config ${YAMLCPP} ${MYSQL_LIBRARY}) ``` #### 步骤4:重新构建项目 完成上述修改后,重新运行CMake和make: ```bash cmake . make ``` ### 注意事项 1. 如果项目中有多个地方使用MySQL,建议将版本兼容性的处理封装到一个头文件中,例如`mysql_compat.h`,然后在需要的地方包含该头文件。 2. 如果系统上安装了多个版本的MySQL,可以通过设置`MYSQL_DIR`环境变量来指定使用MySQL路径,然后在CMake中使用`HINTS`来指定查找路径。 ### 示例代码(mysql_compat.h) ```cpp #ifndef MYSQL_COMPAT_H #define MYSQL_COMPAT_H #include <mysql.h> #if MYSQL_VERSION_ID >= 80000 typedef bool my_bool; #else // 在旧版本中,my_bool已经定义,所以不需要重复定义 #endif #endif // MYSQL_COMPAT_H ``` 在需要使用`my_bool`的地方,包含此头文件,并使用`my_bool`类型。 ### 相关问题 1. 如何在不同操作系统上安装特定版本的MySQL Connector/C? 2. 在CMake中如何更灵活地处理不同版本的依赖库? 3. 如何编写跨版本的数据库访问层代码? 通过以上步骤,应该能够解决编译时遇到的MySQL相关错误。如果问题仍然存在,请检查MySQL头文件和库的路径是否正确,以及代码中是否还有其他不兼容的地方。</think>### 解决 Sylar 编译中 MySQL 相关错误:my_bool 未声明和结构体成员缺失 #### 问题原因分析 1. **MySQL 版本兼容性问题**:MySQL 8.0 及以上版本移除了 `my_bool` 类型[^1],改用标准 `bool` 类型 2. **头文件包含问题**:未正确包含 MySQL 头文件或使用了过时的头文件路径 3. **API 变更**:MySQL Connector/C 8.0 重构了 `MYSQL_BIND` 结构体,移除了 `is_null` 等成员 --- ### 解决方案(逐步操作) #### 步骤 1:修改 MySQL 兼容性代码 在包含 MySQL 头文件前添加类型重定义(推荐在 `sylar/db/mysql.h` 中添加): ```cpp // 解决 my_bool 兼容性问题 #if MYSQL_VERSION_ID >= 80000 typedef bool my_bool; #else typedef char my_bool; // 旧版本定义 #endif ``` #### 步骤 2:更新 MySQL 结构体访问方式 修改使用 `MYSQL_BIND` 结构体的代码(如 `sylar/db/mysql.cc`): ```cpp // 替换旧版成员访问方式 #if MYSQL_VERSION_ID >= 80000 bind[i].is_null = &is_null; // 新版使用指针 bind[i].error = &error; #else bind[i].is_null = is_null; // 旧版直接赋值 bind[i].error = error; #endif ``` #### 步骤 3:更新 CMake 配置 修改 `CMakeLists.txt` 确保正确包含 MySQL 头文件(参考引用[1]): ```cmake # 添加 MySQL 头文件路径 include_directories(/usr/include/mysql) # Ubuntu 默认路径 # include_directories(/usr/local/mysql/include) # macOS 常用路径 # 添加 MySQL 库链接 find_library(MYSQL_LIB mysqlclient PATHS /usr/lib/mysql /usr/local/mysql/lib) target_link_libraries(your_target_name ${MYSQL_LIB}) ``` #### 步骤 4:安装正确版本的 MySQL 开发包 ```bash # Ubuntu/Debian sudo apt install libmysqlclient-dev # CentOS/RHEL sudo yum install mysql-community-devel # macOS (Homebrew) brew install mysql-client ``` #### 步骤 5:验证 MySQL 头文件路径 在终端执行以下命令确认路径: ```bash mysql_config --include # 输出头文件路径 mysql_config --libs # 输出库文件路径 ``` 在 CMake 中使用输出路径更新 `include_directories()` 和 `link_directories()` --- ### 完整示例:MySQL 兼容性处理 ```cpp // sylar/db/mysql.h #pragma once #include <mysql/mysql.h> #if MYSQL_VERSION_ID >= 80000 typedef bool my_bool; #else typedef char my_bool; #endif namespace sylar { class MySQLStmt { public: struct BindData { #if MYSQL_VERSION_ID >= 80000 bool is_null = false; bool error = false; #else my_bool is_null = 0; my_bool error = 0; #endif // ... 其他成员 }; // ... 类实现 }; } // namespace sylar ``` --- ### 补充说明 1. **版本检测宏**:`MYSQL_VERSION_ID` 是 MySQL 提供的版本标识(如 80021 表示 8.0.21) 2. **API 变更文档**:参考 [MySQL 8.0 C API 变更](https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-11.html#mysqld-8-0-11-c-api) 3. **兼容性建议**:建议在 Docker 中固定 MySQL 开发环境版本[^2]
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值