python-3.x - 使用 Python 和 SQL Server 根据分层规则进行分类
问题描述
简短的摘要
我正在寻找有关根据具有层次结构的规则在 Python 3.9 中进行分类的解决方案设计的建议,以及有关如何存储规则的建议。
详细说明
我在 Python 中有一堆具有相似属性的数据,例如代表某公司的员工。实际的表示可能在字典中或在某些类似数据持有者的类中。可能的属性是字符串(例如名字和姓氏)、浮点数(小时工资或最高税率)、整数(今年和剩余的休假天数)和日期(开始就业日期、出生日期)。有些也可以是枚举(例如性别)。此外,这些类型的结构也是可能的,例如今年所有休假日的日期列表。
我还有一些具有层次关系的规则,如下所示:
- 字段 + 运算符 + 值:例如位置 == 经理。员工的任何字段都有效,运算符可以是 ==、<、<=、>=、> 或基本字符串函数,如 contains/startswith/endswith/regexMatch。(例如姓氏包含“儿子”是可以的。)
- 其他规则的布尔组合(例如,如果我们定义 (A) 姓氏以“AK”开头并且 (B) 工资 > 100K,则 [(A) 和 (B)]、[not (B)] 和 [( A) 或 (B)] 都可以。)
- 可以选择性地假设至少有一条规则适用于任何相关员工,但不一定如此。
我想设计一个解决方案
- 将规则存储在 SQL Server 2018 中(以某种可管理的形式)。
- 能够从数据库中读取规则并(有效地)将规则应用于一堆相似的员工对象,因为每个人都可以找出层次结构中与每个特定员工匹配的第一条规则(或者没有一个规则会 - 一些变化是由于上面的潜在假设(3),这里是可能的)。
我正在寻找设计建议以及使用哪些 Python 库来有效地实现这一点。
示例实现 1
一个建议我可以建议如何实现和存储我想要的东西。
- 将每条规则分解为基本规则(折叠层次结构),并使用带有特殊“and”/“or”/“not”节点的 JSON 模式来表示它。
- 长期存储在 SQL Server 中,
varchar()
但可以使用JSON_VALUE
等JSON_QUERY
来处理它。 - 直接消费到 Python 中,将字符串转换为 JSON 模式
- 要应用规则,请使用
Cerberus
Python 库根据每个规则的架构验证每个员工持有人,直到其中一个匹配。
例如,如果我们有记录(第一个、最后一个、年龄、薪水)
- 约翰·多伊 (John, Doe), 43, 50000
- 亚历克斯, 梅斯, 65, 43000
和规则
- A.30.30 : {last 以 A..K 开头,年龄 <= 30,薪水 <= 30k}
- A.50.30 : {last 以 A..K 开头,30 < 年龄 <= 50,工资 <= 30k}
- A.70.30 : {last 以 A..K 开头,50 < 年龄,薪水 <= 30k}
- A.30.70 : {last 以 A..K 开头,年龄 <= 30,30k < 工资 <= 70k}
- A.50.70 : {last 以 A..K 开头,30 < 年龄 <= 50, 30k < 工资 <= 70k}
- A.70.70 : {last 以 A..K 开头,50 < 年龄,30k < 工资 <= 70k}
- A.30.100 : {last 以 A..K 开头,年龄 <= 30, 70k < 薪水}
- A.50.100 : {last 以 A..K 开头,30 < 年龄 <= 50, 70k < 薪水}
- A.70.100 : {last 以 A..K 开头,50 < 年龄,70k < 薪水}
- 同样对于 B.?.? 最后将从 M..Z 开始
首先将规则应用于 John Doe:
- A.30.30:姓氏正常,年龄不匹配
- A.50.30:姓氏ok,年龄ok,工资不匹配
- A.70.30:姓氏正常,年龄不匹配
- A.30.70:姓氏正常,年龄不匹配
- A.50.70:姓氏ok,年龄ok,薪水ok
所以 John Doe 被标记为 A.50.70。注意这里有大量额外的比较,因为比较的层次结构被忽略了。
这很好,因为如果规则结构发生变化,我们只需要更改规则层次结构,而不是代码。这个解决方案的问题是
- 将许多规则应用于员工是非常低效的,因为沿着第一条规则的路径不会影响可能非常相关的其他规则;和
- 将规则存储为 JSON 听起来不是一个好主意,因为直观地检查所用属性的数据以及它们的使用方式变得非常成问题。
我想得到更好的解决方案的建议,请。我很高兴使用 Python 库来轻松处理这个问题,而不是尽可能自己实现。谢谢你。
解决方案
推荐阅读
- amazon-s3 - AWS DMS 将 RDS(MariaDB) 迁移到镶木地板中的 S3
- flutter - 如何在颤动中删除一些线的填充?
- linux - 在每行的最后一个字段中将具有特定条件的行打印到另一个文件中
- python - 如何访问嵌套在字典列表中的字典的值
- python - 错误:“* 不支持的操作数类型:'Equality' 和 'float'”
- python - 使用 Ipywidgets 多个下拉菜单更改数据框的字段名称
- powerbi - 按列和度量排名
- python - Python脚本创建意外结果
- locust - 在 locust 中模拟 100 RPS 需要多少用户?
- http - 如何摆脱 WinHttpReceiveResponse 12030 错误