wiki:DatabaseCreation

Version 2 (modified by 231075, 13 days ago) ( diff )

--

DatabaseCreation

Имплементација на базата

Релационата база на податоци е имплементирана во PostgreSQL според претходно дефинираниот релационен модел.

Структурата на базата е дефинирана во:

За генерирање на податоците кои се користат при пополнување и тестирање на базата се користи:

Генерирање и внесување на податоци

Податоците се генерираат со Python скрипта и се запишуваат во CSV датотеки кои одговараат на табелите од базата.

За генерирањето се користи Faker, при што е поставен фиксен seed за резултатите да можат повторно да се репродуцираат:

SEED = 42

fake = Faker()
Faker.seed(SEED)
random.seed(SEED)

За запишување на генерираните записи се користи заедничка функција:

@contextmanager
def csv_writer(filename: str, fieldnames: list):
path = OUT_DIR / filename
with path.open("w", newline="", encoding="utf-8") as f:
w = csv.DictWriter(f, fieldnames=fieldnames)
w.writeheader()
yield w

Основни податоци

Најпрво се генерираат податоците за табелите од кои зависат останатите записи. На пример, статусите на проектите се дефинирани на следниот начин:

STATUSES = [
"Draft",
"In Progress",
"On Hold",
"Completed",
"Cancelled",
"Under Review"
]

write_csv(
"project_status.csv",
["status_id", "status_name"],
[
{"status_id": i + 1, "status_name": s}
for i, s in enumerate(STATUSES)
],
)

На сличен начин се генерираат и Role, Permission, Industry, Technology, Rating_Dimension и Subscription_Tier.

Клиенти и продавачи

Записите за клиентите и продавачите се генерираат со реалистични имиња, веб страници и контакт информации:

write_csv(
"vendor.csv",
["vendor_id", "agency_name", "website"],
[
{
"vendor_id": i + 1,
"agency_name": fake.company(),
"website": fake.url()
}
for i in range(NUM_VENDORS)
],
)

write_csv(
"client.csv",
["client_id", "industry_id", "company_name", "contact_email"],
[
{
"client_id": i + 1,
"industry_id": random.choice(industry_ids),
"company_name": fake.company(),
"contact_email": fake.company_email(),
}
for i in range(NUM_CLIENTS)
],
)

industry_id се избира од претходно генерираните индустрии, со што се почитува врската помеѓу Client и Industry.

Корисници

За различните типови на корисници се генерираат заедничките податоци од табелата User:

user_rows.append(
{
"user_id": uid,
"type": user_type,
"first_name": fake.first_name(),
"last_name": fake.last_name(),
"email": fake.unique.email(),
"password_hash": hashlib.sha256(
fake.password().encode()
).hexdigest(),
"is_active": random.random() > 0.25,
"last_login_at": nullable(rand_ts(1), 0.30),
"created_at": rand_ts(3),
"updated_at": rand_ts(1),
}
)

Потоа корисниците се поврзуваат со соодветниот клиент, продавач или management улога:

write_csv(
"client_user.csv",
["user_id", "client_id"],
[
{
"user_id": u,
"client_id": random.choice(client_ids)
}
for u in client_user_ids
],
)

Проекти

При генерирање на проект се користат веќе постоечки договори и проектни статуси:

w.writerow(
{
"project_id": i + 1,
"contract_id": random.choice(contract_ids),
"status_id": random.choice(status_ids),
"project_name": fake.catch_phrase(),
"start_date": sd,
"end_date": ed,
"budget": round(random.uniform(1_000, 250_000), 2),
}
)

Со ова секој проект е поврзан со валиден Client_Vendor_Contract и Project_Status.

За many-to-many врската помеѓу проектите и технологиите се генерираат записи во Project_Technology:

with csv_writer(
"project_technology.csv",
["project_id", "technology_id"]
) as w:
for pid in project_ids:
for tid in random.sample(
tech_ids,
random.randint(1, 5)
):
w.writerow(
{
"project_id": pid,
"technology_id": tid
}
)

Рецензии и оценки

Рецензиите се поврзуваат со постоечки проект и клиентски корисник:

w.writerow(
{
"review_id": rid,
"project_id": pid,
"client_user_id": random.choice(client_user_ids),
"review_date": rand_date(0, 3),
"summary_text": fake.paragraph(nb_sentences=3),
"is_published": random.random() > 0.30,
}
)

Оценките за рецензиите се внесуваат посебно во Review_Score:

with csv_writer(
"review_score.csv",
["review_id", "dimension_id", "score_value"]
) as w:
for rid in review_ids:
for did in dim_ids:
w.writerow(
{
"review_id": rid,
"dimension_id": did,
"score_value": random.randint(1, 5),
}
)

На овој начин секоја оценка се поврзува со соодветна рецензија и димензија на оценување.

Историја и промени на податоците

За да се зачува историјата на буџетот на проектите се генерираат записи со стара и нова вредност:

w.writerow(
{
"audit_id": audit_id,
"project_id": pid,
"old_budget": old_b,
"new_budget": round(
old_b * random.uniform(0.6, 1.6),
2
),
}
)

Исто така се генерира историја на промена на статусите преку Project_Status_History, како и податоци за Dispute_Ticket.

Полнење на базата

Скриптата генерира поголем број реалистични записи за различните делови од системот, вклучувајќи клиенти, продавачи, договори, проекти, технологии, рецензии и нивните зависни записи.

Податоците се генерираат во редослед кој ги почитува foreign key зависностите помеѓу табелите. За поголемите табели се генерира доволно големо количество на податоци за тестирање на базата со реалистично оптоварување.

Генерирањето се извршува со:

Error: Failed to load processor bash
No macro or processor named 'bash' found

Attachments (4)

Download all attachments as: .zip

Note: See TracWiki for help on using the wiki.