Prima di tutto fissare il modello un po '. Nel tuo schema hai più attributi per dimensione: id e nome, potresti avere più dettagli in futuro. È possibile aggiungerli specificando gli attributi come elenco: "attriubtes": ["id", "name"]
. Si noti inoltre che la dimensione è denominata come entità product
non come chiave id_product
. La chiave id_product
è solo un attributo della dimensione product
, così come lo è name
o in futuro forse category
. La dimensione riflette il punto di vista degli analisti.
Per il momento, ignoriamo il fatto che la data dovrebbe essere una dimensione speciale e considerare la data come chiave a valore singolo, ad esempio un anno, per non complicare le cose qui.
"dimensions": [
{"name": "user", "attributes": ["id", "name"]},
{"name": "product", "attributes": ["id", "name"]},
{"name": "date"}
],
Perché abbiamo cambiato i nomi delle dimensioni, dobbiamo cambiare loro in lista dimensione del cubo:
"cubes": [
{
"name": "purchases",
"dimensions": ["user", "product", "date"],
...
schema riflette classico schema transazionale, non tradizionale schema di data warehouse. In questo caso, devi essere esplicito, come sei, e menzionare tutte le mappature necessarie. La regola è: se l'attributo appartiene a una tabella dei fatti (vista logica), la chiave è solo attribute
, ad esempio price
, nessuna specifica tabella. Se l'attributo appartiene a una dimensione, ad esempio product.id
, la sintassi è dimension.attribute
. Il valore del dizionario dei mapping è la tabella fisica e la colonna fisica. Vedi more information about mappings. Mappature per lo schema simile:
"mappings": {
"price": "products.price",
"product.id": "products.id",
"product.name": "products.name",
"user.id": "users.id",
"user.name": "users.name"
}
che non avrebbe dovuto scrivere mappature se lo schema era:
fact purchases
id | date | user_id | product_id | amount
dimension product
id | name | price
dimension user
id | name
In questo caso sarà necessario unisce solo, perché tutti gli attributi di dimensione sono nel loro rispettivo tabelle dimensionali. Nota il amount
nella tabella dei fatti, che nel tuo caso, poiché non hai count
di prodotti acquistati per acquisto, sarebbe lo stesso di price
in product
.
Ecco il modello aggiornato per il modello:
{
"dimensions": [
{"name": "user", "attributes": ["id", "name"]},
{"name": "product", "attributes": ["id", "name"]},
{"name": "date"}
],
"cubes": [
{
"name": "purchases",
"dimensions": ["user", "product", "date"],
"measures": ["price"],
"mappings": {
"price": "products.price",
"product.id": "products.id",
"product.name": "products.name",
"user.id": "users.id",
"user.name": "users.name"
},
"joins": [
{
"master": "purchases.user_id",
"detail": "users.id"
},
{
"master": "purchases.product_id",
"detail": "products.id"
}
]
}
]
}
È possibile provare il modello senza scrivere codice Python, semplicemente utilizzando il comando slicer
.Per questo è necessario slicer.ini
configuration file:
[server]
backend: sql
port: 5000
log_level: info
prettyprint: yes
[workspace]
url: sqlite:///data.sqlite
[model]
path: model.json
Variazione url
in [workspace]
per puntare al database e cambiare path
in [model]
per puntare al file di modello. Ora si può provare:
curl "http://localhost:5000/aggregate"
cercano anche di drill-down:
curl "http://localhost:5000/aggregate?drilldown=product"
Se avete bisogno di ulteriore aiuto, fammelo sapere, io sono l'autore Cubes.
OLAP non è progettato per eseguire join. Utilizzare invece un database SQL, forse. –
@AaronWatters Il framework Python's Cubes fornisce questa funzionalità. È un backend MySQL. – user1491915
Per chiarire: i join sono nascosti all'utente finale, fanno parte della mappatura logico-fisico e sono specificati nel modello logico. Inoltre, Cubes ha molti backend di database relazionali, non solo MySQL, tutti backend supportati da SQLAlchemy. Ciò include: PostgreSQL, Oracle, SQLite e molti altri. – Stiivi