Zillion
是一种数据建模和分析工具,可以通过简单的API组合和分析来自多个数据源的数据。 SQL写道,它是数据顶部的语义层,因此您不必这样做,并且可以通过SQLalchemy Core轻松地将其螺栓固定到现有的数据库基础架构上。 Zillion
NLP扩展具有对AI驱动的自然语言查询和仓库配置的实验支持。
有Zillion
您可以:
警告:该项目处于α国家,可能会发生变化。请仔细测试生产使用情况并报告任何问题。
$ pip install zillion
or
$ pip install zillion[nlp]
以下内容旨在快速概述数据仓库中使用的一些理论和命名Zillion
,如果您对该领域更新,这将很有用。您还可以跳过下面的使用示例或仓库/数据源创建QuickStart选项。
简而言之: Zillion
为您写入SQL,并通过非常简单的API访问数据:
result = warehouse . execute (
metrics = [ "revenue" , "leads" ],
dimensions = [ "date" ],
criteria = [
( "date" , ">" , "2020-01-01" ),
( "partner" , "=" , "Partner A" )
]
)
在Zillion
中,您的报告请求中将使用两种主要Fields
类型:
Dimensions
:用于标记,分组和过滤的数据的属性Metrics
:可能沿维度分解的事实和措施一个Field
封装了数据中列的概念。例如,您可能有一个名为“收入”的Field
。该Field
可能发生在几个数据源中,也可能发生在单个数据源中的多个表中。 Zillion
了解到所有这些列代表相同的概念,并且可以尝试使用其中任何一个来满足要求“收入”的报告。
同样,有两种主要的表用于构建您的仓库:
Dimension Tables
:参考/属性表仅包含相关维度Metric Tables
:可能包含指标和一些相关维度/属性的事实表尺寸表通常是静态的或在行计数方面逐渐增长,并且包含与主键相关的属性。一些常见的示例将是美国邮政编码或公司/合作伙伴目录的列表。
公制表通常本质上是更大的交易。一些常见的例子将是网络请求,电子商务销售或股票市场价格历史记录的记录。
如果您真的想深入了解尺寸建模,而Birs-across查询技术则使用了Zillion
,我建议阅读拉尔夫·金博尔(Ralph Kimball)的数据仓库书。
总而言之,钻孔查询构成一个或多个查询,以满足报告要求在特定dimension
粒的多个数据源和/或表中可能存在的metrics
请求。
Zillion
支持灵活的仓库设置,例如Snowflake或Star Schemas,尽管对此并不挑剔。您可以通过亲子谱系来指定表关系,而Zillion
也可以根据尺寸表主键的存在来推断可接受的连接。 Zillion
目前不支持许多与众不同的关系,尽管大多数以分析为中心的方案应该能够通过在需要的情况下添加视图来解决此问题。
可以将Zillion
报告视为两层运行:
DataSource Layer
:针对仓库数据源的SQL查询Combined Layer
:针对数据源层的组合数据的最终SQL查询组合层只是另一个SQL数据库(默认情况下是内存的SQLITE),用于将数据源数据连接在一起,并应用一些其他功能,例如汇总,行滤镜,行限制,排序,枢轴和技术计算。
有多种方法可以快速从本地或远程文件初始化仓库:
# Path/link to a CSV, XLSX, XLS, JSON, HTML, or Google Sheet
# This builds a single-table Warehouse for quick/ad-hoc analysis.
url = "https://raw.githubusercontent.com/totalhack/zillion/master/tests/dma_zip.xlsx"
wh = Warehouse . from_data_file ( url , [ "Zip_Code" ]) # Second arg is primary key
# Path/link to a sqlite database
# This can build a single or multi-table Warehouse
url = "https://github.com/totalhack/zillion/blob/master/tests/testdb1?raw=true"
wh = Warehouse . from_db_file ( url )
# Path/link to a WarehouseConfigSchema (or pass a dict)
# This is the recommended production approach!
config = "https://raw.githubusercontent.com/totalhack/zillion/master/examples/example_wh_config.json"
wh = Warehouse ( config = config )
千亿美元还提供了一个辅助脚本来为现有数据库boostrap buostrap。请参阅zillion.scripts.bootstrap_datasource_config.py
。 Bootstrap脚本需要一个连接/数据库URL和输出文件作为参数。有关更多选项,包括可选的--nlp
标志,请参阅--help
输出,该选项利用OpenAI推断配置信息,例如列类型,表类型和表格关系。 NLP功能需要安装NLP扩展名,以及Zillion
配置文件中的以下设置:
Zillion
的主要目的是针对Warehouse
执行报告。在高水平上,您将按照以下方式制定报告:
result = warehouse . execute (
metrics = [ "revenue" , "leads" ],
dimensions = [ "date" ],
criteria = [
( "date" , ">" , "2020-01-01" ),
( "partner" , "=" , "Partner A" )
]
)
print ( result . df ) # Pandas DataFrame
与编写SQL相比,将尺寸视为SQL语句的组的目标列是有帮助的。将指标视为您正在汇总的列。将标准视为其中的条款。您的标准应用于数据源层SQL查询。
ReportResult
具有熊猫数据框架,其尺寸为索引和指标作为列。
据说有一份grain
,该Report
定义了每个指标必须能够加入的尺寸,以满足Report
要求。 grain
是所有维度的组合,包括标准或公制公式中引用的谷物。在上面的示例中, grain
将为{date, partner}
。 “收入”和“潜在客户”都必须能够加入这些维度,以使本报告成为可能。
这些概念可能需要时间才能沉入,并且显然会随数据模型的细节而变化,但是随着您开始针对数据仓库进行报告时,您会变得更加熟悉它们。
随着NLP的扩展, Zillion
对您的数据仓库的自然语言查询提供了实验支持。例如:
result = warehouse . execute_text ( "revenue and leads by date last month" )
print ( result . df ) # Pandas DataFrame
此NLP功能需要QDRANT(Vector Database)的运行实例,并且在您的Zillion
配置文件中设置了以下值:
嵌入将产生并存储在QDRANT和局部缓存中。矢量数据库将在您第一次尝试通过分析仓库中的所有字段来初始化。此存储库的根部提供了一个用于运行QDRANT的示例Docker文件。
您可以控制字段如何嵌入。也就是说,在任何字段的配置中,您可以选择是将字段从嵌入式或嵌入到该字段的层面上排除的字段。默认情况下所有字段都包含。以下示例将将net_revenue
字段排除在嵌入,并将revenue
指标请求映射到gross_revenue
字段。
{
"name" : "gross_revenue" ,
"type" : "numeric(10,2)" ,
"aggregation" : "sum" ,
"rounding" : 2 ,
"meta" : {
"nlp" : {
// enabled defaults to true
"embedding_text" : "revenue" // str or list of str
}
}
} ,
{
"name" : "net_revenue" ,
"type" : "numeric(10,2)" ,
"aggregation" : "sum" ,
"rounding" : 2 ,
"meta" : {
"nlp" : {
"enabled" : false
}
}
} ,
此外,您还可以通过以下仓库级配置设置排除字段:
{
"meta" : {
"nlp" : {
"field_disabled_patterns" : [
// list of regex patterns to exclude
"rpl_ma_5"
] ,
"field_disabled_groups" : [
// list of "groups" to exclude, assuming you have
// set group value in the field's meta dict.
"No NLP"
]
}
} ,
...
}
如果在上述任何一个级别上禁用字段,它将被忽略。这种类型的控件变得有用,因为您的数据模型变得更加复杂,并且您想在可能混淆类似命名字段的情况下指导NLP逻辑。每当您调整哪些字段被排除在外时,您都需要使用Warehouse.init_embeddings
上的force_recreate
标志强制嵌入嵌入收集。
注意:此功能还处于起步阶段。它的有用性取决于输入查询和您的数据模型的质量(即好的字段名称)!
除了配置Warehouse
的结构(将在下面的进一步讨论)外, Zillion
还具有全局配置来控制某些基本设置。 ZILLION_CONFIG
环境VAR可以指向YAML配置文件。有关可以设置哪些值的更多详细信息,请参见examples/sample_config.yaml
。带有Zillion_前缀的环境可以覆盖配置设置(即Zillion_db_url将覆盖DB_URL)。
可以通过将Zillion
配置中的db_url值设置为有效的数据库连接字符串来配置用于存储千亿美元报告规格的数据库。默认情况下,使用 /tmp中的sqlite db。
在下面,我们将浏览一个简单的假设销售数据模型,该模型展示了基本的DataSource
和Warehouse
配置,然后显示一些示例报告。数据是一个简单的SQLITE数据库,是Zillion
测试代码的一部分。作为参考,该模式如下:
CREATE TABLE partners (
id INTEGER PRIMARY KEY ,
name VARCHAR NOT NULL UNIQUE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE campaigns (
id INTEGER PRIMARY KEY ,
name VARCHAR NOT NULL UNIQUE,
category VARCHAR NOT NULL ,
partner_id INTEGER NOT NULL ,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE leads (
id INTEGER PRIMARY KEY ,
name VARCHAR NOT NULL ,
campaign_id INTEGER NOT NULL ,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE sales (
id INTEGER PRIMARY KEY ,
item VARCHAR NOT NULL ,
quantity INTEGER NOT NULL ,
revenue DECIMAL ( 10 , 2 ),
lead_id INTEGER NOT NULL ,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
可以通过JSON或YAML配置创建Warehouse
,该配置定义其字段,数据量和表。下面的代码显示,如果您有指向JSON/YAML Warehouse
配置的指针,则如何在一行代码中完成。
from zillion import Warehouse
wh = Warehouse ( config = "https://raw.githubusercontent.com/totalhack/zillion/master/examples/example_wh_config.json" )
此示例配置在其DataSource
connect
中使用data_url
信息,该信息告诉Zillion
,以动态下载数据并将其连接到SQLITE数据库中。这对于快速示例或分析很有用,尽管在大多数情况下,您会将连接字符串放在现有数据库中,就像您在此处看到
Zillion's
仓库配置结构的基础如下:
Warehouse
配置具有以下主要部分:
metrics
:全局度量标准配置的可选列表dimensions
:全局维度尺寸配置的可选列表datasources
:数据源名称到数据源配置或配置URL的映射DataSource
配置具有以下主要部分:
connect
:数据库连接URL或连接参数的distmetrics
:特定于此数据源的公制配置的可选列表dimensions
:特定于此数据源的尺寸配置的可选列表tables
:将表名称映射到表配置或配置URL提示:数据源和表配置也可以用指向本地或远程配置文件的URL替换。
在此示例中,我们的数据库中的所有四个表都包含在配置中,两个作为尺寸表,两个作为度量表。表通过父母的关系:竞选活动的合作伙伴并导致销售。一些表还利用create_fields
标志从列定义从数据源上自动创建Fields
。其他指标和维度是明确定义的。
要查看Init之后此Warehouse
的结构,您可以使用print_info
方法,该方法显示所有是数据仓库一部分的指标,尺寸,表和列:
wh . print_info () # Formatted print of the Warehouse structure
有关配置模式的更深入研究,请参阅完整的文档。
示例:获得合作伙伴的销售,潜在客户和收入:
result = wh . execute (
metrics = [ "sales" , "leads" , "revenue" ],
dimensions = [ "partner_name" ]
)
print ( result . df )
"""
sales leads revenue
partner_name
Partner A 11 4 165.0
Partner B 2 2 19.0
Partner C 5 1 118.5
"""
示例:让我们限制合作伙伴A并因其广告系列而分解:
result = wh . execute (
metrics = [ "sales" , "leads" , "revenue" ],
dimensions = [ "campaign_name" ],
criteria = [( "partner_name" , "=" , "Partner A" )]
)
print ( result . df )
"""
sales leads revenue
campaign_name
Campaign 1A 5 2 83
Campaign 2A 6 2 82
"""
示例:下面的输出显示了每个合作伙伴内活动级别的汇总,以及在合作伙伴和活动级别上的总数。
注意:输出包含一个特殊字符,以标记添加到结果中的数据帧汇总行。记录对象包含一些用于自动访问或过滤汇总的辅助属性,以及
df_display
属性,该属性返回结果,返回结果,以友好的显示值替换为特殊字符。在此处留下的特殊角色以供插图,但在所有情况下可能并不相同。
from zillion import RollupTypes
result = wh . execute (
metrics = [ "sales" , "leads" , "revenue" ],
dimensions = [ "partner_name" , "campaign_name" ],
rollup = RollupTypes . ALL
)
print ( result . df )
"""
sales leads revenue
partner_name campaign_name
Partner A Campaign 1A 5.0 2.0 83.0
Campaign 2A 6.0 2.0 82.0
� 11.0 4.0 165.0
Partner B Campaign 1B 1.0 1.0 6.0
Campaign 2B 1.0 1.0 13.0
� 2.0 2.0 19.0
Partner C Campaign 1C 5.0 1.0 118.5
� 5.0 1.0 118.5
� � 18.0 7.0 302.5
"""
有关支持的汇总行为的更多信息,请参见Report
文档。
示例:保存报告规格(不是数据):
首先,您必须确保已保存Warehouse
,因为保存的报告范围范围为特定的Warehouse
ID。要保存Warehouse
,您必须提供指向完整配置的URL。
name = "My Unique Warehouse Name"
config_url = < some url pointing to a complete warehouse config >
wh . save ( name , config_url ) # wh.id is populated after this
spec_id = wh . save_report (
metrics = [ "sales" , "leads" , "revenue" ],
dimensions = [ "partner_name" ]
)
注意:如果您从
DataSources
列表中构建了python的Warehouse
,或以init的config
param on Initdict
,那么当前没有一种内置方法可以在保存时将完整的配置输出到文件中以供参考。
示例:从规格ID加载并运行报告:
result = wh . execute_id ( spec_id )
这是假设您以前已将此报告ID保存在db_url在Zillion
美元配置中指定的数据库中。
示例:未支撑的谷物
如果您尝试了不可能的报告,您将获得UnsupportedGrainException
GrainException。下面的报告是不可能的,因为它试图通过仅存在于子表中的维度来分解潜在客户指标。一般而言,儿童桌子可以与父母(父母的“兄弟姐妹”)相连,以找到维度,但不能相反。
# Fails with UnsupportedGrainException
result = wh . execute (
metrics = [ "leads" ],
dimensions = [ "sale_id" ]
)
有时,您需要类似子查询的功能才能将一个报告过滤到其他一些结果(可能需要不同的谷物)的结果。千亿美元提供了一种简单的方法,可以通过not in report
标准操作中使用in report
或不使用报告。有两种支持的方法来指定子报告:传递报告规格ID或传递报告参数的dist。
# Assuming you have saved report 1234 and it has "partner" as a dimension:
result = warehouse . execute (
metrics = [ "revenue" , "leads" ],
dimensions = [ "date" ],
criteria = [
( "date" , ">" , "2020-01-01" ),
( "partner" , "in report" , 1234 )
]
)
# Or with a dict:
result = warehouse . execute (
metrics = [ "revenue" , "leads" ],
dimensions = [ "date" ],
criteria = [
( "date" , ">" , "2020-01-01" ),
( "partner" , "in report" , dict (
metrics = [...],
dimension = [ "partner" ],
criteria = [...]
))
]
)
in report
是否在not in report
使用的标准字段必须是子报告中的一个维度。请注意,子报告是在Report
对象初始化时间而不是在execute
过程中执行的 - 因此,它们无法使用Report.kill
杀死它们。这可能会改变道路。
在上面的示例中,我们的配置包括一个基于公式的指标,称为“ RPL”,它只是revenue / leads
。 FormulaMetric
结合了其他指标和/或维度,以在查询的组合层处计算新的度量。语法必须匹配您的组合图层数据库,该数据库在我们的示例中是SQLITE。
{
"name" : " rpl " ,
"aggregation" : " mean " ,
"rounding" : 2 ,
"formula" : " {revenue}/{leads} "
}
为了方便起见,您不必重复定义核心度量的速率变体的公式指标,而是可以在非格式公制上指定除数公式的配置。例如,假设您有revenue
指标,并希望为revenue_per_lead
和revenue_per_sale
创建变体。您可以按以下方式定义收入指标:
{
"name" : " revenue " ,
"type" : " numeric(10,2) " ,
"aggregation" : " sum " ,
"rounding" : 2 ,
"divisors" : {
"metrics" : [
" leads " ,
" sales "
]
}
}
有关配置选项的更多详细信息,例如覆盖命名模板,公式模板和舍入,请参见zillion.configs.DivisorsConfigSchema
另一个较小的便利功能是能够自动生成单个字段配置中不同聚合类型的指标变体,而不是配置文件中的多个字段。例如,假设您的数据中有一个sales
列,并希望为sales_mean
和sales_sum
创建变体。您可以按以下方式定义指标:
{
"name" : " sales " ,
"aggregation" : {
"mean" : {
"type" : " numeric(10,2) " ,
"rounding" : 2
},
"sum" : {
"type" : " integer "
}
}
}
由此产生的仓库将没有sales
指标,而是拥有sales_mean
和sales_sum
。请注意,您可以通过在该聚合类型的嵌套设置中指定该设置的生成字段的设置,例如设置自定义名称。在实践中,这不是分别定义指标的效率,但有些人可能更喜欢这种方法。
也存在针对FormulaDimension
领域的实验支持。 FormulaDimension
只能将其他维度用作其公式的一部分,并且还可以在组合图层数据库中进行评估。作为另一个限制,由于在数据源层中评估了这些过滤器,因此无法在报告标准中使用FormulaDimension
。下面的示例假定一个SQLite组合图层数据库:
{
"name" : " partner_is_a " ,
"formula" : " {partner_name} = 'Partner A' "
}
我们的示例还包括一个度量“销售”,其价值是通过在查询数据源层上通过公式计算的。在“ main.sales”表中的“ ID”参数的fields
列表中注意以下内容。这些公式在特定DataSource
数据库技术的语法中,在我们的示例中也恰好是SQLITE。
"fields" : [
" sale_id " ,
{ "name" : " sales " , "ds_formula" : " COUNT(DISTINCT sales.id) " }
]
我们的示例还自动从线索和销售表的“创建”列中创建了一些维度。支持自动类型转换是有限的,但是对于支持的DataSource
技术中的日期/日期列列,您可以通过这种方式免费获得各种维度。
wh.print_info
的输出将显示添加的尺寸,该维度由每个表中的配置中的可选type_conversion_prefix
指定的前缀为“ leds_”或“ sale_”。我们的示例仓库中的自动生成维度的一些示例包括sale_hour,sale_day_name,sale_month,sale_year等。
作为基础报告查询的Where子句中的优化, Zillion
将尝试将转换应用于标准值而不是列。例如,查询为my_datetime > '2020-01-01' and my_datetime < '2020-01-02'
而不是DATE(my_datetime) == '2020-01-01'
,通常更有效地有效,因为后者可以在许多数据库技术中预防索引使用。将转换为值而不是列的能力也随字段和DataSource
技术而变化。
要防止键入转换,请将skip_conversion_fields
设置为true
在您的DataSource
配置上。
有关当前支持的转换的更多详细信息,请参见zillion.field.TYPE_ALLOWED_CONVERSIONS
and zillion.field.DIALECT_CONVERSIONS
。
您还可以在每个报告请求中定义“临时”指标。以下是一个示例,它可以随时创建一个逐步的度量。这些仅存在于报告的范围内,该名称不能与任何现有字段冲突:
result = wh . execute (
metrics = [
"leads" ,
{ "formula" : "{revenue}/{leads}" , "name" : "my_rpl" }
],
dimensions = [ "partner_name" ]
)
您还可以在每个报告请求中定义“临时”尺寸。下面是一个示例,该示例创建了一个尺寸,该维度可以在特定维度值上分配。临时维度是FormulaDimension
S的子类,因此具有相同的限制,例如无法将度量作为公式字段。这些仅存在于报告的范围内,该名称不能与任何现有字段冲突:
result = wh . execute (
metrics = [ "leads" ],
dimensions = [{ "name" : "partner_is_a" , "formula" : "{partner_name} = 'Partner A'" ]
)
Zillion
还支持在DataSource
或Warehouse
init期间在数据库中的临时表的创建或同步。此处显示的表配置的示例。它使用表配置的data_url
和if_exists
参数来控制SQLite数据库中远程CSV的“ main.dma_zip”表的同步和/或创建。在其他数据库类型中也可以做同样的事情。
这种方法的潜在性能弊端应该是显而易见的,尤其是如果您经常初始化仓库或远程数据文件很大。通常最好提前同步和创建数据,以便您拥有完整的模式控制,但是在某些情况下,此方法可能非常有用。
警告:请注意不要覆盖数据库中的现有表!
可以将多种技术计算应用于指标来计算滚动,累积或等级统计。例如,为了计算收入的5分移动平均值,一个人可能会定义一个新的指标:如下:
{
"name" : " revenue_ma_5 " ,
"type" : " numeric(10,2) " ,
"aggregation" : " sum " ,
"rounding" : 2 ,
"technical" : " mean(5) "
}
技术计算是在组合层上计算的,而“聚合”是在数据源层进行的(因此需要在上面定义这两个)。
有关速记技术字符串如何解析的更多信息,请参见parse_technical_string代码。有关支持的技术类型的完整列表,请参见zillion.core.TechnicalTypes
。
技术还支持两种模式:“组”和“全部”。该模式控制如何在数据维度上应用技术计算。在“组”模式下,它计算了最后一个维度的技术,而在“所有”模式中,“所有”模式在所有数据上计算技术,而无需考虑维度。
如果您尝试在[“ panters_name”,“ date”]类似的数据中进行“库姆”技术,那么这一点将变得更加清楚。如果使用“组”模式(在大多数情况下默认)将在每个合作伙伴内在日期范围内进行累积总和。如果使用“所有”模式,它将在每个数据行中进行累积总和。您可以通过将模式附加到技术字符串上来明确说明该模式:IE“ cumsum:ass ass”或“平均(5):group”
如果您想避免将敏感的连接信息直接放在DataSource
配置中,则可以利用配置变量。在您Zillion
YAML配置中,您可以指定DATASOURCE_CONTEXTS
部分,如下所示:
DATASOURCE_CONTEXTS :
my_ds_name :
user : user123
pass : goodpassword
host : 127.0.0.1
schema : reporting
然后,当读取名为“ my_ds_name”数据源DataSource
配置时,它可以使用此上下文来填充连接URL中的变量:
"datasources" : {
"my_ds_name" : {
"connect" : " mysql+pymysql://{user}:{pass}@{host}/{schema} "
...
}
}
在Warehouse
INIT上,您可以按名称指定数据量的默认优先顺序。当多个数据源可以满足报告时,这将发挥作用。列表中较早的DataSources
将是更高的优先级。如果您想偏爱将DataSource
中的一组更快的汇总表组成的速度,这将很有用。
wh = Warehouse ( config = config , ds_priority = [ "aggr_ds" , "raw_ds" , ...])
Zillion's
目标是支持SQLalchemy支持的任何数据库技术(如下图所示)。那就是当前Zillion
支持和测试水平变化。特别是,进行键入转换,数据库反射和杀死的能力都需要一些数据库特定的代码来支持。以下列表总结了已知的支持级别。 SQLalchemy支持的未经测试的数据库技术可能会有所不同(它可能效果很好,尚未经过测试)。请报告错误并帮助添加更多支持!
Sqlalchemy具有许多流行数据库的连接器。考虑到Zillion
操作的简单性质,支持其中许多的障碍可能很低。
请注意,以上与组合图层数据库的数据库支持不同。目前,那里只有Sqlite。对于大多数用例,这应该足够,但是将在道路上增加更多选择。
如果您打算在多进程方案中运行Zillion
,无论是在一个节点上还是跨多个节点,都有几件事要考虑:
请注意,您仍然可以在没有问题的情况下使用默认的SQLite内存中组合db,因为这是在每个报告请求时即时进行的,并且不需要与其他过程或节点的协调/通信。
数十亿个Web UI是一个千亿美元的演示UI和Web API,还包括一个实验性Chatgpt插件。有关安装和项目结构的更多信息,请参见README。请注意,该代码是测试和抛光剂的灯光,但有望在现代浏览器中使用。此刻,ChatGpt插件也很慢,因此目前主要是为了娱乐而不是那么有用。
可以在此处找到更彻底的文档。您可以通过仔细阅读测试目录或API参考来补充知识。
请参阅贡献指南以获取更多信息。如果您正在寻找灵感,添加支持和测试其他数据库技术将是一个很好的帮助。