ISEE小语
《羊皮卷》中有一句话:“人真的忙起来,根本没有太多复杂情绪;人太闲,才会把鸡毛蒜皮当回事。”
本次分享是由于小栈在实际中,在查询多个数据库中的users_msg表时,有的库中有en_name,有的库中没有这个字段,在实现过程中出现
1054 - Unknown column 'en_name' in 'field list'
由于固执己见,踩了坑,这里来记录一个简单的例子
环境:
Python | 3.9.16 |
三方库 | mysql-connector-python==8.1.0 PyMySQL==1.1.0 |
安装:
pip install mysql-connector-python==8.1.0
pip install PyMySQL==1.1.0
前提准备
小栈本地环境的Mysql的版本是5.7.32
有的users_msg表中有字段id,name,age,score
有的表字段是id,name,en_name,age,score
基本查询
接下来查询id为8,en_name的值
SELECT en_name FROM users_msg WHERE id=8;
(左右滑动查看完整代码)
两个结果,
第一个库没有en_name字段的表,结果:
提示【Unknown column 'en_name' in 'field list'】
第二个库的存在en_name字段的表,结果:
固执己见的小栈认为可以直接一个sql搞定,开始网上查阅资料
网上方式
方式一:使用COALESCE函数的机制来实现
这里的意思是通过COALESCE函数会检查en_name的值,如果en_name是NULL,它就返回default_name;否则,返回en_name的实际值。
SELECT
COALESCE(en_name, 'default_name') AS en_name
FROM
users_msg
WHERE
id = 8;
(左右滑动查看完整代码)
很遗憾,这个方式不可以,看一下结果:
但这个方式适合在当前表中已经存在的字段,如果这个字段的值为NULL,使用这个方式,它就返回default_name;否则,返回en_name的实际值。
方式二:使用IFNULL函数
这里的意思是通过IFNULL函数用于将NULL值替换为指定的默认值。
SELECT
IFNULL(en_name, 'default_name') AS en_name
FROM
users_msg
WHERE
id = 8;
(左右滑动查看完整代码)
很遗憾,这个方式仍不可以
实际使用效果,与以上COALESCE函数的方式类似
方式三:使用IF语句结合EXISTS条件
这里的意思是通过查询users_msg表中是否存在en_name字段,如果不存在则返回默认值,否则返回en_name的实际值。
SELECT
CASE
WHEN EXISTS (
SELECT 1
FROM information_schema.`COLUMNS`
WHERE table_name='users_msg' AND COLUMN_name = 'en_name'
) THEN en_name
ELSE 0
END AS en_name_exists
FROM
users_msg
WHERE
id = 8;
(左右滑动查看完整代码)
很遗憾,这个方式也不可以
这个方式看逻辑实现很清晰,感觉没有什么问题,但仍会提示【1054 - Unknown column 'en_name' in 'field list'】
原因是由于不能直接使用CASE WHEN EXISTS来处理字段不存在的情况
小栈总结
以上三种处理方式,均未能解决,是因为查询本身需要知道字段是否存在才能执行。
如果尝试在查询中使用不存在的字段,MySQL会抛出一个【1054 - Unknown column 'en_name' in 'field list'】的错误,指出该字段是未知的。
这个基本常识性的问题,让好奇心盖过去了。
结果就是,一个sql处理,小栈没搞定
小栈方式
接下来,在实现逻辑里面处理
首先,先查en_name字段是否存在
exists_sql = "SELECT 1 FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = 'self_test' AND table_name='users_msg' AND COLUMN_name = 'en_name' LIMIT 1;"
cursor.execute(exists_sql)
is_exists = cursor.fetchone()
print(is_exists)
(左右滑动查看完整代码)
以上执行的结果:
如果'en_name'存在,输出:(1,)
如果'en_name'不存在,输出:None
然后,根据输出的结果进行判断,再进行查询
if is_exists:
# 如果存在,则返回en_name的实际值
_sql = "SELECT en_name FROM users_msg WHERE id = 8;"
else:
# 如果不存在,则返回赋给en_name的默认值
_sql = "SELECT 'default_name' AS en_name FROM users_msg WHERE id = 8;"
cursor.execute(_sql)
result = cursor.fetchone()
print(result)
主要代码
如果没有前期固执己见的纠结,其实会很简单
# -*- coding: utf-8 -*-
import mysql.connector
# 连接MySql
db_config = {
'host': '127.0.0.1',
'user': 'root',
'password': '123456',
'port': 3306,
'database': 'self_test'
}
cnx = mysql.connector.connect(**db_config)
cursor = cnx.cursor()
exists_sql = "SELECT 1 FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = 'self_test' AND table_name='users_msg' AND COLUMN_name = 'en_name' LIMIT 1;"
cursor.execute(exists_sql)
is_exists = cursor.fetchone()
print(is_exists)
if is_exists:
# 如果存在,则返回en_name的实际值
_sql = "SELECT en_name FROM users_msg WHERE id = 8;"
else:
# 如果不存在,则返回赋给en_name的默认值
_sql = "SELECT 'default_name' AS en_name FROM users_msg WHERE id = 8;"
cursor.execute(_sql)
result = cursor.fetchone()
print(result)
# 结束
(左右滑动查看完整代码)
总结
小栈记录,只为个过程。
结果实现上可能会有更好的方式,也可能一个sql能搞定,但小栈放弃了。
如果哪位朋友有更好的方式,希望给小栈留个言,小栈还是想“固执己见”。
上面提到的数据库,在以往的文章中分享过,小栈直接拿过来使用的
Python实现MySql数据库导出表结构和数据功能-实例
ISEE小栈,公众号:ISEE小栈Python实现MySql数据库导出表结构和数据功能-实例
【Mysql】合集中有几篇实例,有兴趣的同学可以看看,挺有意思。
有兴趣的朋友点个“赞”和“在看”,谢谢支持~!
文章就分享到这儿,喜欢就点个赞吧!