mirror of
https://github.com/spring-projects/spring-petclinic.git
synced 2025-07-22 07:45:49 +00:00
Add migration script
This commit is contained in:
parent
0aa3adb56f
commit
50713cb2a7
13 changed files with 285 additions and 0 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -15,3 +15,5 @@ build/*
|
||||||
_site/
|
_site/
|
||||||
*.css
|
*.css
|
||||||
!petclinic.css
|
!petclinic.css
|
||||||
|
|
||||||
|
venv
|
||||||
|
|
|
@ -25,3 +25,13 @@ services:
|
||||||
- POSTGRES_DB=petclinic
|
- POSTGRES_DB=petclinic
|
||||||
profiles:
|
profiles:
|
||||||
- postgres
|
- postgres
|
||||||
|
|
||||||
|
mongodb:
|
||||||
|
image: mongo:7.0.4
|
||||||
|
environment:
|
||||||
|
MONGO_INITDB_ROOT_USERNAME: petclinic
|
||||||
|
MONGO_INITDB_ROOT_PASSWORD: petclinic
|
||||||
|
ports:
|
||||||
|
- "27017:27017"
|
||||||
|
profiles:
|
||||||
|
- mongodb
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
database=h2
|
database=h2
|
||||||
spring.sql.init.schema-locations=classpath*:db/${database}/schema.sql
|
spring.sql.init.schema-locations=classpath*:db/${database}/schema.sql
|
||||||
spring.sql.init.data-locations=classpath*:db/${database}/data.sql
|
spring.sql.init.data-locations=classpath*:db/${database}/data.sql
|
||||||
|
spring.h2.console.enabled=true
|
||||||
|
|
||||||
# Web
|
# Web
|
||||||
spring.thymeleaf.mode=HTML
|
spring.thymeleaf.mode=HTML
|
||||||
|
@ -23,3 +24,4 @@ logging.level.org.springframework=INFO
|
||||||
|
|
||||||
# Maximum time static resources should be cached
|
# Maximum time static resources should be cached
|
||||||
spring.web.resources.cache.cachecontrol.max-age=12h
|
spring.web.resources.cache.cachecontrol.max-age=12h
|
||||||
|
|
||||||
|
|
15
src/main/resources/db/mongo/README.md
Normal file
15
src/main/resources/db/mongo/README.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# Requirements
|
||||||
|
- python > 3.9
|
||||||
|
|
||||||
|
# How to set up python environment
|
||||||
|
- run `python -m venv venv`
|
||||||
|
- run `source venv/bin/activate`
|
||||||
|
- run `pip install -r requirements.txt`
|
||||||
|
|
||||||
|
# How to set up mongo db
|
||||||
|
- run `docker-compose --profile=mongodb up`
|
||||||
|
- run `python migrate.py`
|
||||||
|
- connection string - `mongodb://petclinic:petclinic@localhost:27017/`
|
||||||
|
- username - `petclinic`
|
||||||
|
- password - `petclinic`
|
||||||
|
- db - `petclinic`
|
11
src/main/resources/db/mongo/csv-files/owners.csv
Normal file
11
src/main/resources/db/mongo/csv-files/owners.csv
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
"ID";"FIRST_NAME";"LAST_NAME";"ADDRESS";"CITY";"TELEPHONE"
|
||||||
|
"1";"George";"Franklin";"110 W. Liberty St.";"Madison";"6085551023"
|
||||||
|
"2";"Betty";"Davis";"638 Cardinal Ave.";"Sun Prairie";"6085551749"
|
||||||
|
"3";"Eduardo";"Rodriquez";"2693 Commerce St.";"McFarland";"6085558763"
|
||||||
|
"4";"Harold";"Davis";"563 Friendly St.";"Windsor";"6085553198"
|
||||||
|
"5";"Peter";"McTavish";"2387 S. Fair Way";"Madison";"6085552765"
|
||||||
|
"6";"Jean";"Coleman";"105 N. Lake St.";"Monona";"6085552654"
|
||||||
|
"7";"Jeff";"Black";"1450 Oak Blvd.";"Monona";"6085555387"
|
||||||
|
"8";"Maria";"Escobito";"345 Maple St.";"Madison";"6085557683"
|
||||||
|
"9";"David";"Schroeder";"2749 Blackhawk Trail";"Madison";"6085559435"
|
||||||
|
"10";"Carlos";"Estaban";"2335 Independence La.";"Waunakee";"6085555487"
|
|
14
src/main/resources/db/mongo/csv-files/pets.csv
Normal file
14
src/main/resources/db/mongo/csv-files/pets.csv
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
"ID";"NAME";"BIRTH_DATE";"TYPE_ID";"OWNER_ID"
|
||||||
|
"1";"Leo";"2010-09-07";"1";"1"
|
||||||
|
"2";"Basil";"2012-08-06";"6";"2"
|
||||||
|
"3";"Rosy";"2011-04-17";"2";"3"
|
||||||
|
"4";"Jewel";"2010-03-07";"2";"3"
|
||||||
|
"5";"Iggy";"2010-11-30";"3";"4"
|
||||||
|
"6";"George";"2010-01-20";"4";"5"
|
||||||
|
"7";"Samantha";"2012-09-04";"1";"6"
|
||||||
|
"8";"Max";"2012-09-04";"1";"6"
|
||||||
|
"9";"Lucky";"2011-08-06";"5";"7"
|
||||||
|
"10";"Mulligan";"2007-02-24";"2";"8"
|
||||||
|
"11";"Freddy";"2010-03-09";"5";"9"
|
||||||
|
"12";"Lucky";"2010-06-24";"2";"10"
|
||||||
|
"13";"Sly";"2012-06-08";"1";"10"
|
|
4
src/main/resources/db/mongo/csv-files/specs.csv
Normal file
4
src/main/resources/db/mongo/csv-files/specs.csv
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
"ID";"NAME"
|
||||||
|
"3";"dentistry"
|
||||||
|
"1";"radiology"
|
||||||
|
"2";"surgery"
|
|
7
src/main/resources/db/mongo/csv-files/types.csv
Normal file
7
src/main/resources/db/mongo/csv-files/types.csv
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
"ID";"NAME"
|
||||||
|
"5";"bird"
|
||||||
|
"1";"cat"
|
||||||
|
"2";"dog"
|
||||||
|
"6";"hamster"
|
||||||
|
"3";"lizard"
|
||||||
|
"4";"snake"
|
|
7
src/main/resources/db/mongo/csv-files/vets.csv
Normal file
7
src/main/resources/db/mongo/csv-files/vets.csv
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
"ID";"FIRST_NAME";"LAST_NAME"
|
||||||
|
"1";"James";"Carter"
|
||||||
|
"2";"Helen";"Leary"
|
||||||
|
"3";"Linda";"Douglas"
|
||||||
|
"4";"Rafael";"Ortega"
|
||||||
|
"5";"Henry";"Stevens"
|
||||||
|
"6";"Sharon";"Jenkins"
|
|
6
src/main/resources/db/mongo/csv-files/vets_specs.csv
Normal file
6
src/main/resources/db/mongo/csv-files/vets_specs.csv
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
"VET_ID";"SPECIALTY_ID"
|
||||||
|
"2";"1"
|
||||||
|
"3";"2"
|
||||||
|
"3";"3"
|
||||||
|
"4";"2"
|
||||||
|
"5";"1"
|
|
6
src/main/resources/db/mongo/csv-files/visits.csv
Normal file
6
src/main/resources/db/mongo/csv-files/visits.csv
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
"ID";"PET_ID";"VISIT_DATE";"DESCRIPTION"
|
||||||
|
"1";"7";"2013-01-01";"rabies shot"
|
||||||
|
"2";"8";"2013-01-02";"rabies shot"
|
||||||
|
"3";"8";"2013-01-03";"neutered"
|
||||||
|
"4";"7";"2013-01-04";"spayed"
|
||||||
|
"5";"5";"2024-01-06";"kjhjkhhjk"
|
|
200
src/main/resources/db/mongo/migrate.py
Normal file
200
src/main/resources/db/mongo/migrate.py
Normal file
|
@ -0,0 +1,200 @@
|
||||||
|
from pymongo import MongoClient
|
||||||
|
from dataclasses import dataclass
|
||||||
|
from datetime import date, datetime
|
||||||
|
from uuid import UUID, uuid4
|
||||||
|
import csv
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
|
FILE_PATHS = {
|
||||||
|
"vets": "csv-files/vets.csv",
|
||||||
|
"specs": "csv-files/specs.csv",
|
||||||
|
"vets_specs": "csv-files/vets_specs.csv",
|
||||||
|
"types": "csv-files/types.csv",
|
||||||
|
"owners": "csv-files/owners.csv",
|
||||||
|
"pets": "csv-files/pets.csv",
|
||||||
|
"visits": "csv-files/visits.csv"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class VetRow:
|
||||||
|
id: str
|
||||||
|
first_name: str
|
||||||
|
last_name: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Vet:
|
||||||
|
first_name: str
|
||||||
|
last_name: str
|
||||||
|
speciality: Optional[str]
|
||||||
|
|
||||||
|
def to_dict(self) -> dict:
|
||||||
|
return {
|
||||||
|
"first_name": self.first_name,
|
||||||
|
"last_name": self.last_name,
|
||||||
|
"speciality": self.speciality
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class VisitRow:
|
||||||
|
id: str
|
||||||
|
pet_id: str
|
||||||
|
visit_date: str
|
||||||
|
description: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Visit:
|
||||||
|
visit_date: date
|
||||||
|
description: str
|
||||||
|
|
||||||
|
def to_dict(self) -> dict:
|
||||||
|
return {
|
||||||
|
"visit_date": self.visit_date,
|
||||||
|
"description": self.description
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class PetRow:
|
||||||
|
id: str
|
||||||
|
name: str
|
||||||
|
birth_date: str
|
||||||
|
type_id: str
|
||||||
|
owner_id: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Pet:
|
||||||
|
name: str
|
||||||
|
birth_date: date
|
||||||
|
type: str
|
||||||
|
visits: list[Visit]
|
||||||
|
|
||||||
|
def to_dict(self) -> dict:
|
||||||
|
return {
|
||||||
|
"name": self.name,
|
||||||
|
"birth_date": self.birth_date,
|
||||||
|
"type": self.type,
|
||||||
|
"visits": [visit.to_dict() for visit in self.visits]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class OwnerRow:
|
||||||
|
id: str
|
||||||
|
first_name: str
|
||||||
|
last_name: str
|
||||||
|
address: str
|
||||||
|
city: str
|
||||||
|
telephone: str
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class Owner:
|
||||||
|
first_name: str
|
||||||
|
last_name: str
|
||||||
|
address: str
|
||||||
|
city: str
|
||||||
|
telephone: str
|
||||||
|
pets: dict[UUID: Pet]
|
||||||
|
|
||||||
|
def to_dict(self) -> dict:
|
||||||
|
return {
|
||||||
|
"first_name": self.first_name,
|
||||||
|
"last_name": self.last_name,
|
||||||
|
"address": self.address,
|
||||||
|
"city": self.city,
|
||||||
|
"telephone": self.telephone,
|
||||||
|
"pets": {pet_id: pet.to_dict() for pet_id, pet in self.pets.items()}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> None:
|
||||||
|
with open(FILE_PATHS["types"], newline='') as types_file:
|
||||||
|
reader = csv.reader(types_file, delimiter=';')
|
||||||
|
next(reader, None)
|
||||||
|
types_map = {int(row[0]): row[1] for row in reader}
|
||||||
|
|
||||||
|
with open(FILE_PATHS["specs"], newline='') as specs_file:
|
||||||
|
reader = csv.reader(specs_file, delimiter=';')
|
||||||
|
next(reader, None)
|
||||||
|
specs_map = {int(row[0]): row[1] for row in reader}
|
||||||
|
|
||||||
|
with open(FILE_PATHS["vets_specs"], newline='') as vet_specs_file:
|
||||||
|
reader = csv.reader(vet_specs_file, delimiter=';')
|
||||||
|
next(reader, None)
|
||||||
|
vet_specs_map = {int(row[0]): int(row[1]) for row in reader}
|
||||||
|
|
||||||
|
with open(FILE_PATHS["vets"], newline='') as vet_file:
|
||||||
|
reader = csv.reader(vet_file, delimiter=';')
|
||||||
|
next(reader, None)
|
||||||
|
vet_rows = [VetRow(*row) for row in reader]
|
||||||
|
|
||||||
|
with open(FILE_PATHS["visits"], newline='') as visits_file:
|
||||||
|
reader = csv.reader(visits_file, delimiter=';')
|
||||||
|
next(reader, None)
|
||||||
|
visits_rows = [VisitRow(*row) for row in reader]
|
||||||
|
|
||||||
|
with open(FILE_PATHS["pets"], newline='') as pets_file:
|
||||||
|
reader = csv.reader(pets_file, delimiter=';')
|
||||||
|
next(reader, None)
|
||||||
|
pet_rows = [PetRow(*row) for row in reader]
|
||||||
|
|
||||||
|
with open(FILE_PATHS["owners"], newline='') as owners_file:
|
||||||
|
reader = csv.reader(owners_file, delimiter=';')
|
||||||
|
next(reader, None)
|
||||||
|
owner_rows = [OwnerRow(*row) for row in reader]
|
||||||
|
|
||||||
|
vets = [
|
||||||
|
Vet(
|
||||||
|
first_name=row.first_name,
|
||||||
|
last_name=row.last_name,
|
||||||
|
speciality=specs_map.get(vet_specs_map.get(int(row.id), -1))
|
||||||
|
) for row in vet_rows
|
||||||
|
]
|
||||||
|
|
||||||
|
owners = [
|
||||||
|
Owner(
|
||||||
|
first_name=row.first_name,
|
||||||
|
last_name=row.last_name,
|
||||||
|
address=row.address,
|
||||||
|
city=row.city,
|
||||||
|
telephone=row.telephone,
|
||||||
|
pets={
|
||||||
|
str(uuid4()): Pet(
|
||||||
|
name=pet_row.name,
|
||||||
|
birth_date=datetime.strptime(pet_row.birth_date, '%Y-%m-%d'),
|
||||||
|
type=types_map[int(pet_row.type_id)],
|
||||||
|
visits=[
|
||||||
|
Visit(
|
||||||
|
visit_date=datetime.strptime(visit_row.visit_date, '%Y-%m-%d'),
|
||||||
|
description=visit_row.description
|
||||||
|
) for visit_row in visits_rows
|
||||||
|
]
|
||||||
|
) for pet_row in pet_rows
|
||||||
|
}
|
||||||
|
) for row in owner_rows
|
||||||
|
]
|
||||||
|
|
||||||
|
client = MongoClient('mongodb://petclinic:petclinic@localhost:27017/')
|
||||||
|
db = client['petclinic']
|
||||||
|
|
||||||
|
vets_collection = db['vets']
|
||||||
|
owners_collection = db['owners']
|
||||||
|
specs_collection = db["specializations"]
|
||||||
|
types_collection = db["types"]
|
||||||
|
|
||||||
|
vets_collection.insert_many([vet.to_dict() for vet in vets])
|
||||||
|
owners_collection.insert_many([owner.to_dict() for owner in owners])
|
||||||
|
specs_collection.insert_many([{"name": name} for name in specs_map.values()])
|
||||||
|
types_collection.insert_many([{"name": name} for name in types_map.values()])
|
||||||
|
|
||||||
|
print("Migration done")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
1
src/main/resources/db/mongo/requirements.txt
Normal file
1
src/main/resources/db/mongo/requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
pymongo
|
Loading…
Reference in a new issue