Leetao's Blog

Talk is cheap, show me the code

0%

前言

Field 是 MySQL 中的一个函数,其基本使用方法如下:
作用
用于返回指定值在给定值列表中的索引位置
语法

1
FIELD(value, val1, val2, val3, ...)

例子

1
SELECT FIELD("q", "s", "q", "l");

上面的 sql 就是返回字母 qs,q,l 中的位置,这里和编程语言中不一样,返回的下标是从 1 开始的,所以上述的返回结果是 2

如果查找的字符不在列表里呢?

1
SELECT field("a","s", "q", "l");

返回为 0 ,结果如下:

应用场景

说完了,基本用法,说一下 Field 的应用场景,单纯从函数推测出它的应用场景,但是它的实际应用场景,在某种程度上还是很实用的,它可以自定义排序
所谓的自定义排序就是按照我们给定的顺序对数据结果进行排序,通常情况下,我们通过 order by field 无外乎就是降序或者升序排列,但是在某些特殊的业务场景下,你可能预期按照自己的规则去定义排序。

例子

如下表所示

默认的情况下,显然是按照 id 进行升序排列的,但是如果需要按照人名 a,c,b,d来排序。也就是 name=a,c,b,d 来排序。
这个时候就可以借由 field 函数去实现了:

1
SELECT * FROM user ORDER BY FIELD(name, 'a','c','b','d')

执行结果如下:

延伸

现在 user 表里新增了三条记录:

现在有这样子的需求,需要将记录先按照 x,y,z 排序,后面按照正常排序即结果如下:

如何可以做到?
原理其实很简单,归根结底就是 order byfield 的联合应用。首先需要明白,order by 的排序原理,order by 原理其实很简单,就是按照我们给定的排序字段(升序或者降序排列)

为什么 ‘a’,’c’,’b’,’d’

这个时候,再回到最初 user 表只有四条记录时,按照 a,c,b,d 排序

1
SELECT * FROM user ORDER BY FIELD(name, 'a','c','b','d')

这个 sql 发生了什么?

我们用 Field 函数构建了一个临时的排序字段,不同的 name 返回在 field 下返回不同的值,相当于构成了一个新的 sort_field 字段

所以这个时候结果就会按照 a,c,b,d 的顺序排列了。

如何 x,y,z 然后 a,b,c,d

首先如果如果按照 x,y,z 在最前面的要求,sql 应当是:

1
SELECT * FROM user ORDER BY FIELD(name, 'x','y','z')

结果如下:

这个时候的 sort_field 表现是这样子的:

我们预期的应当是

如果只是将排序由升序改为降序

1
SELECT * FROM user ORDER BY FIELD(name, 'x','y','z') DESC

这个时候结果如下:

这个结果已经接近 预期了,我们只需要将 field 后面的 x,y,z 变成 z,y,x 就可以了

1
SELECT * FROM user ORDER BY FIELD(name, 'z','y','x') DESC

结果如下:

以下例子均的运行环境为 Python 3.9.5,不同版本的实际运行结果可能有所不同

前言

前端时间看了 Golang 的 学习了一下 数组 和 Slice,其中 Slice 相当于动态数组,其中数组的长度是固定的,而 Slice 则是不定长的。在 Python 中是没有数组和 Slice 的概念,它们可以通通归类为 List(列表),那么问题来了,定长的 List 和 不定长的 List 在表现上会有区别吗?(这里的定长的 List 是指对 List 进行初始化,也就是所谓的预分配)
接下来通过几个例子去验证这个问题。

阅读全文 »

以下例子以 mysql 为准

前言

django orm 中关于更新,有两种操作分别是:

  1. update
  2. bulk_update

对于 createbulk_create 这俩类,毫无疑问存在大量数据插入的时候,后者效率更高一些。但是对于更新则需要根据实际情况进行分析了,了解 django 是如何实现 bulk_update ,对于我们使用会有一定的好处。

bulk_update 的应用场景是,每个需要更新的数据的 value 值各不相同,如果是相同,则没有必要去使用 bulk_update

阅读全文 »

前言

在实际开发中,有时候需要用 Python 去处理一些 JSON 文件,一旦 JSON 文件过大,就有可能出现加载时间过长,内存消耗过大的问题,甚至会导致内存耗尽。所以如果正确地处理大的 JSON 文件呢?

阅读全文 »

前言

在 Java 中有 [[重载]] 的概念:

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

Python 本身不支持 重载 这个特性,但是通过 functools.singledispatch 可以实现函数的重载。接下来通过一个例子,简单地演示一下 Python 的函数重载。

阅读全文 »

django 默认 bulk_create 不支持 signal,可以通过自定义 models.Manager 支持这个特性

1
2
3
4
5
6
7
8
9
10
class CustomManager(models.Manager):  
def bulk_create(self, items, **kwargs):
for i in items:
post_save.send(i.__class__, instance=i, created=True)
return super().bulk_create(items, **kwargs)

def bulk_update(self, items, fields, **kwargs):
super().bulk_update(items, fields, **kwargs)
for i in items:
post_save.send(i.__class__, instance=i, created=False)

使用实例:

1
2
3
class Test(db.models):
objects = CustomManager()
...

前言

lru_cache 是 functools 库中的一个函数,它为函数提供缓存功能的装饰器,缓存 maxsize 组传入参数,在下次以相同参数调用时直接返回上一次的结果。

从它的功能来说是一个不错的方法,可以在一定程度上提高函数的运行速度,但是它存在一个问题,当你用functools.lru_cache装饰器来装饰一个实例方法时,封装该方法的类的实例在持有它们的进程中永远不会被垃圾回收。

阅读全文 »

为了保证 Python 的代码规范,在使用 git commit 提交代码之前,需要使用 blake、isort 工具对提交的文件进行格式化,如果提交的代码符合规法则 commit 成功,否则自动格式化文件,然后重新 commit

整个工作流大概是这样子:

其中 black 是代码格式化工具,可以通过 pip install black 后直接使用,使用方法如下:

1
black {source_file_or_directory}...

同时也支持配置文件自定义规则,详细内容可以参考官方文档 The uncompromising code formatter — Black

isort 则是用来规范 python 库的引入的,按字母顺序对 packages 进行排序,并自动分为不同的部分和类型,同样可以通过 pip install isort 后直接使用,使用方法如下:

1
isort mypythonfile.py mypython file2.py

black 一样也支持配置文件自定义规则,具体内容参考官网 isort (pycqa.github.io)

pre-commit 是整个工作流最重要的一环,pre-commitgit-hooks 中的一个重要的钩子,它在键入提交信息前运行。可以用于检查即将提交的快照,例如,检查是否有所遗漏,确保测试运行,以及核查代码。 如果该钩子以非零值退出,Git 将放弃此次提交。 上面提到的机制是整个工作流可以进行的关键。

完全可以自定义 pre-commit 钩子的,但是如果只是为了检验的话,可以使用现成的方案 pre-commit/pre-commit,用 Python 构建,支持多语言的管理器。通过 pre-commit 这个库,简单地几步就可以实现自动化工作流。

  1. 安装 pre-commit
1
pip install pre-commit

然后通过 pre-commit --version 确定是否安装成功

1
2
$ pre-commit --version
pre-commit 2.16.0
  1. 添加 .pre-commit-config.yaml 的配置文件

可以通过 pre-commit sample-config 生成一个默认的配置文件,这里贴一下关于 blackisort 的配置文件

1
2
3
4
5
6
7
8
9
10
repos:  
- repo: https://github.com/psf/black
rev: 21.12b0
hooks:
- id: black

- repo: https://github.com/PyCQA/isort
rev: 5.10.1
hooks:
- id: isort

支持的配置项很多,具体参考 plugins

  1. 安装 git hooks 脚本
1
2
$ pre-commit install
pre-commit installed at .git/hooks/pre-commit

然后就就大功告成了