Fix bugs after source extraction from dengfun
This commit is contained in:
parent
03da817878
commit
907bc9f3c5
42
README.md
42
README.md
|
@ -2,4 +2,44 @@
|
||||||
|
|
||||||
* [documentation](https://psychic-broccoli-r4ome5j.pages.github.io/)
|
* [documentation](https://psychic-broccoli-r4ome5j.pages.github.io/)
|
||||||
|
|
||||||
Implementation of a digital twin of a retail corporation that operates a chain of grocery stores will be described. The implementation is of course limited but comprehensive enough to get some key insights about why corporate IT looks the way it looks. If anyone intends to create antifragile data systems it's important to study how fragile systems come to be on the first place.
|
Implementation of a digital twin of a retail corporation that operates a chain of grocery stores will be described. The implementation is of course limited but comprehensive enough to get some key insights about why corporate IT looks the way it looks. If anyone intends to create antifragile data systems it's important to study how fragile systems come to be on the first place.
|
||||||
|
|
||||||
|
## Bootstrap the database
|
||||||
|
|
||||||
|
First create a postgresql database.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
createdb -h localhost -U postgresuser retail
|
||||||
|
```
|
||||||
|
|
||||||
|
In this case we decided to call the database `retail` and we created it in the same computer we will be running the digital twin. Then sync the data models in the freshly created database with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
retailtwin.exe init postgresql://postgresuser:password@localhost/retail
|
||||||
|
```
|
||||||
|
|
||||||
|
Then we can populate the database with dummy data with the `bootstrap` subcommand:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
retailtwin.exe bootstrap postgresql://postgresuser:password@localhost/retail
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally we can create all the necessary functions, procedures, and triggers with
|
||||||
|
|
||||||
|
```bash
|
||||||
|
retailtwin.exe sync postgresql://postgresuser:password@localhost/retail
|
||||||
|
```
|
||||||
|
|
||||||
|
## Terminals
|
||||||
|
|
||||||
|
There are currently three available terminals to operate with the digital twin:
|
||||||
|
|
||||||
|
### Stocking terminal
|
||||||
|
|
||||||
|
```bash
|
||||||
|
stock [DB_URI] [Store location]
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
stock postgresql://postgresuser:password@localhost/retail 1
|
||||||
|
```
|
||||||
|
|
|
@ -11,15 +11,18 @@ dependencies = [
|
||||||
"duckdb",
|
"duckdb",
|
||||||
"pydantic",
|
"pydantic",
|
||||||
"typer",
|
"typer",
|
||||||
|
"rich",
|
||||||
"pyyaml",
|
"pyyaml",
|
||||||
"pydantic-settings",
|
"pydantic-settings",
|
||||||
"polars",
|
"polars",
|
||||||
|
"pandas",
|
||||||
"pyarrow",
|
"pyarrow",
|
||||||
"sqlalchemy[asyncio] > 2.0.13",
|
"sqlalchemy[asyncio] > 2.0.13",
|
||||||
"adbc-driver-postgresql",
|
"adbc-driver-postgresql",
|
||||||
"adbc-driver-sqlite",
|
"adbc-driver-sqlite",
|
||||||
"prompt_toolkit",
|
"prompt_toolkit",
|
||||||
"asyncpg",
|
"asyncpg",
|
||||||
|
"psycopg2-binary",
|
||||||
"pydantic-settings"
|
"pydantic-settings"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ from retailtwin.models import (
|
||||||
)
|
)
|
||||||
|
|
||||||
# Some configuration parameters.
|
# Some configuration parameters.
|
||||||
PACKAGE_ROOT = Path(retailtwin.__file__).parent / "retail"
|
PACKAGE_ROOT = Path(retailtwin.__file__).parent
|
||||||
PRODUCT_LIST_FILE = "data/products.csv"
|
PRODUCT_LIST_FILE = "data/products.csv"
|
||||||
DISCOUNT_LIST_FILE = "data/discounts.csv"
|
DISCOUNT_LIST_FILE = "data/discounts.csv"
|
||||||
RANDOM_PEOPLE_FILE = "data/random_people.csv"
|
RANDOM_PEOPLE_FILE = "data/random_people.csv"
|
||||||
|
|
|
@ -64,14 +64,14 @@ def handle_command(command: str, **kwargs):
|
||||||
pl.col("upc"),
|
pl.col("upc"),
|
||||||
pl.col("name"),
|
pl.col("name"),
|
||||||
pl.col("package"),
|
pl.col("package"),
|
||||||
pl.col("price"),
|
pl.col("unitprice"),
|
||||||
pl.col("best_until"),
|
pl.col("best_until"),
|
||||||
pl.col("quantity"),
|
pl.col("quantity"),
|
||||||
]
|
]
|
||||||
).filter(pl.col("upc") == upc)
|
).filter(pl.col("upc") == upc)
|
||||||
console.print(
|
console.print(
|
||||||
df_to_table(
|
df_to_table(
|
||||||
df.with_columns(pl.col("price").cast(str)),
|
df.with_columns(pl.col("unitprice").cast(str)),
|
||||||
title=f"Item {upc} on location {location}",
|
title=f"Item {upc} on location {location}",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
create or replace procedure add_item_to_cart(cart integer, sku integer, quantity integer)
|
create or replace procedure add_item_to_cart(cart integer, upc integer, quantity integer)
|
||||||
language sql
|
language sql
|
||||||
as
|
as
|
||||||
$$
|
$$
|
||||||
INSERT INTO itemsoncart
|
INSERT INTO itemsoncart
|
||||||
("cart", "sku", "quantity")
|
("cart", "upc", "quantity")
|
||||||
values
|
values
|
||||||
($1, $2, $3);
|
($1, $2, $3);
|
||||||
$$;
|
$$;
|
|
@ -3,7 +3,7 @@ from sqlalchemy import create_engine, text
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
import retailtwin
|
import retailtwin
|
||||||
|
|
||||||
PACKAGE_ROOT = Path(retailtwin.__file__).parent / "retail"
|
PACKAGE_ROOT = Path(retailtwin.__file__).parent
|
||||||
|
|
||||||
|
|
||||||
def funcandproc(db_uri: str):
|
def funcandproc(db_uri: str):
|
||||||
|
@ -29,7 +29,7 @@ def funcandproc(db_uri: str):
|
||||||
view_name = predicate.stem.removesuffix(".sql")
|
view_name = predicate.stem.removesuffix(".sql")
|
||||||
with predicate.open() as sql:
|
with predicate.open() as sql:
|
||||||
# First remove the view
|
# First remove the view
|
||||||
session.execute(text(f"drop view {view_name}"))
|
session.execute(text(f"drop view if exists {view_name}"))
|
||||||
session.commit()
|
session.commit()
|
||||||
|
|
||||||
# And sync it
|
# And sync it
|
||||||
|
|
Loading…
Reference in a new issue