PBL (BIG DATA & DATABASE ADVANCE)
Membuat CRUD Menggunakan Python Untuk Menampilkan Database
Langkah 1: Download Dataset
- Unduh dataset
netflix_titles.xlsxdari tautan berikut:
Netflix Dataset. - Simpan file
netflix_titles.xlsxdi folder proyek Anda (Jika belum punya folder proyek, buat saja).
Langkah 2: Import Dataset ke MongoDB
Folder Struktur:
Buat folder proyek Anda seperti ini:
netflix_project/
│
├── netflix_titles.csv # Dataset Anda
├── import_to_mongo.py # Script untuk impor dataset ke MongoDB
File import_to_mongo.py:
- Buka editor teks atau IDE (seperti VS Code, PyCharm, atau Notepad++).
- Buat file baru dengan nama
import_to_mongo.py. - Tempelkan skrip berikut ke file tersebut:
import pandas as pd
from pymongo import MongoClient
import datetime
# Path ke file dataset
file_path = "C:/Users/nxa1s/netflix_project/netflix_titles.xlsx"
# Membaca semua sheet dari file Excel
try:
sheet_data = pd.read_excel(file_path, sheet_name=None, engine='openpyxl')
print("File Excel berhasil dibaca! Sheets ditemukan:")
print(sheet_data.keys()) # Menampilkan nama sheet
except Exception as e:
print(f"Error saat membaca file Excel: {e}")
exit()
# Koneksi ke MongoDB
try:
client = MongoClient("mongodb://localhost:27017/") # Default MongoDB URL
db = client["netflix_db"]
print("Koneksi ke MongoDB berhasil!")
except Exception as e:
print(f"Error saat menghubungkan ke MongoDB: {e}")
exit()
# Proses setiap sheet
for sheet_name, df in sheet_data.items():
print(f"Memproses sheet: {sheet_name}")
# Konversi kolom bertipe datetime.time ke string
for column in df.columns:
if df[column].apply(lambda x: isinstance(x, (datetime.datetime, datetime.time))).any():
print(f"Kolom '{column}' mengandung datetime atau time, mengonversi ke string...")
df[column] = df[column].apply(lambda x: str(x) if isinstance(x, (datetime.datetime, datetime.time)) else x)
# Cek tipe data setelah konversi
print("Tipe data dalam DataFrame setelah konversi:")
print(df.dtypes)
# Simpan data ke MongoDB
try:
data = df.to_dict(orient="records")
collection = db[sheet_name] # Gunakan nama sheet sebagai nama koleksi
collection.insert_many(data) # Menyimpan data dalam bentuk batch
print(f"Data dari sheet '{sheet_name}' berhasil disimpan ke koleksi '{sheet_name}' di MongoDB!")
except Exception as e:
print(f"Error saat menyimpan data dari sheet '{sheet_name}' ke MongoDB: {e}")
4. Jalankan file ini di terminal:
python import_to_mongo.py
5. Jika berhasil, data akan tersimpan dalam database
netflix_db di koleksi netflix_data.Langkah 3: Buat Aplikasi CRUD Menggunakan Python
Folder Struktur:
Struktur folder proyek:
netflix_project/
│
├── app.py # Script Flask utama
├── templates/
│ └── index.html # File HTML untuk antarmuka
└── static/ # Folder untuk file CSS, JS (opsional)
File app.py:
- Buat file baru dengan nama
app.py. - Tempelkan skrip berikut untuk mengelola CRUD:
from flask import Flask, render_template, request, redirect, url_for
from pymongo import MongoClient
from bson.objectid import ObjectId
# Koneksi ke MongoDB
client = MongoClient('mongodb://localhost:27017/') # Sesuaikan jika menggunakan host lain
db = client['netflix_db'] # Mengakses database netflix_db
titles_collection = db['netflix_titles'] # Koleksi utama untuk data judul
categories_collection = db['netflix_titles_category'] # Koleksi untuk data kategori/genre
directors_collection = db['netflix_titles_directors'] # Koleksi untuk data sutradara
app = Flask(__name__)
# Fungsi untuk mengambil genre berdasarkan show_id
def get_genres():
genres = categories_collection.find() # Mengambil semua data kategori
return {genre['show_id']: genre['listed_in'] for genre in genres} # Mapping show_id ke genre
# Fungsi untuk mengambil director berdasarkan show_id
def get_directors():
directors = directors_collection.find() # Mengambil semua data sutradara
return {director['show_id']: director['director'] for director in directors} # Mapping show_id ke director
# Halaman utama untuk menampilkan data dari koleksi utama
@app.route('/')
def index():
titles = titles_collection.find() # Mengambil semua data dari koleksi utama
genre_mapping = get_genres() # Ambil genre berdasarkan show_id
director_mapping = get_directors() # Ambil director berdasarkan show_id
titles_list = [
{
**title,
'id_str': str(title['_id']),
'genre': genre_mapping.get(title.get('show_id'), "Unknown"), # Ambil genre berdasarkan show_id
'director': director_mapping.get(title.get('show_id'), "Unknown") # Ambil sutradara berdasarkan show_id
}
for title in titles
]
return render_template('index.html', titles=titles_list)
# Halaman untuk menambah data baru (Create)
@app.route('/create', methods=['GET', 'POST'])
def create():
genres = get_genres() # Ambil semua genre untuk dropdown
directors = get_directors() # Ambil semua sutradara untuk dropdown
if request.method == 'POST':
title = request.form['title']
director_id = request.form['director'] # Menyimpan sutradara berdasarkan show_id
genre_id = request.form['genre'] # Menyimpan genre berdasarkan show_id
release_year = request.form['release_year']
# Generate show_id otomatis (gunakan format atau cara lain sesuai kebutuhan)
show_id = str(ObjectId()) # Buat show_id baru berdasarkan ObjectId
data = {
'title': title,
'show_id': show_id, # Menyimpan show_id untuk referensi
'director_id': director_id, # Referensi sutradara
'listed_in': genre_id, # Referensi genre
'release_year': int(release_year)
}
titles_collection.insert_one(data)
return redirect(url_for('index'))
return render_template('create.html', genres=genres, directors=directors)
# Halaman untuk memperbarui data (Update)
@app.route('/update/<title_id>', methods=['GET', 'POST'])
def update(title_id):
title = titles_collection.find_one({'_id': ObjectId(title_id)})
title['id_str'] = str(title['_id']) # Konversi ID ke string
genres = get_genres() # Ambil semua genre untuk dropdown
directors = get_directors() # Ambil semua sutradara untuk dropdown
if request.method == 'POST':
title_name = request.form.get('title')
director_id = request.form.get('director')
genre_id = request.form.get('genre')
release_year = request.form.get('release_year')
update_data = {}
# Periksa mana yang ada di form dan lakukan update hanya jika ada perubahan
if title_name:
update_data['title'] = title_name
if director_id:
update_data['director_id'] = director_id
if genre_id:
update_data['listed_in'] = genre_id
if release_year:
update_data['release_year'] = int(release_year)
# Lakukan update hanya pada field yang diubah
if update_data:
titles_collection.update_one(
{'_id': ObjectId(title_id)},
{'$set': update_data}
)
return redirect(url_for('index'))
return render_template('update.html', title=title, genres=genres, directors=directors)
# Halaman untuk menghapus data (Delete)
@app.route('/delete/<title_id>', methods=['GET', 'POST'])
def delete(title_id):
titles_collection.delete_one({'_id': ObjectId(title_id)})
return redirect(url_for('index'))
if __name__ == '__main__':
app.run(debug=True)
Folder templates dan File index.html, create.html, update.html:
- Buat folder
templatesdi dalam proyek Anda. - Buat file
index.html, create.html, update.htmldi dalam foldertemplates. - Tambahkan skrip HTML dasar pada index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Netflix Titles</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 20px;
}
h1 {
color: #333;
}
a {
text-decoration: none;
color: #2752E7;
}
a:hover {
text-decoration: underline;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
}
th, td {
padding: 10px;
text-align: left;
border: 1px solid #ccc;
}
th {
background-color: #f4f4f4;
}
.actions a {
margin-right: 10px;
}
.actions a:last-child {
color: red;
}
</style>
</head>
<body>
<h1>Netflix Titles</h1>
<a href="{{ url_for('create') }}">Add New Title</a>
<table>
<thead>
<tr>
<th>Title</th>
<th>Director</th>
<th>Genre</th>
<th>Release Year</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% if titles %}
{% for title in titles %}
<tr>
<td>{{ title.title or "Unknown" }}</td>
<td>{{ title.director or "Unknown" }}</td>
<td>{{ title.genre or "Unknown" }}</td>
<td>{{ title.release_year or "Unknown" }}</td>
<td class="actions">
<a href="{{ url_for('update', title_id=title.id_str) }}">Edit</a>
<a href="{{ url_for('delete', title_id=title.id_str) }}" onclick="return confirm('Are you sure?')">Delete</a>
</td>
</tr>
{% endfor %}
{% else %}
<tr>
<td colspan="5" style="text-align: center;">No titles found.</td>
</tr>
{% endif %}
</tbody>
</table>
</body>
</html>
4. Tambahkan skrip HTML dasar pada create.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Create Netflix Title</title>
</head>
<body>
<h1>Create New Title</h1>
<form method="post">
<!-- Input show_id secara otomatis -->
<input type="hidden" name="show_id" value="{{ show_id }}"> <!-- show_id otomatis di set oleh backend -->
<label for="title">Title:</label>
<input type="text" id="title" name="title" required><br><br>
<label for="director">Director:</label>
<select id="director" name="director" required>
<option value="">Select Director</option>
{% for director_id, director_name in directors.items() %}
<option value="{{ director_id }}">{{ director_name }}</option>
{% endfor %}
</select><br><br>
<label for="genre">Genre:</label>
<select id="genre" name="genre" required>
<option value="">Select Genre</option>
{% for genre_id, genre_name in genres.items() %}
<option value="{{ genre_id }}">{{ genre_name }}</option>
{% endfor %}
</select><br><br>
<label for="release_year">Release Year:</label>
<input type="number" id="release_year" name="release_year" required><br><br>
<button type="submit">Add Title</button>
</form>
<a href="{{ url_for('index') }}">Cancel</a>
</body>
</html>
5. Tambahkan skrip HTML dasar pada update.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Update Netflix Title</title>
</head>
<body>
<h1>Update Title</h1>
<form method="post">
<!-- Hidden input for show_id to identify the title being updated -->
<input type="hidden" id="show_id" name="show_id" value="{{ title.show_id }}">
<!-- Title Input -->
<label for="title">Title:</label>
<input type="text" id="title" name="title" value="{{ title.title }}"><br><br>
<!-- Director Selection -->
<label for="director">Director:</label>
<select id="director" name="director">
<option value="">Select Director (leave blank to keep current)</option>
{% for director_id, director_name in directors.items() %}
<option value="{{ director_id }}" {% if director_id == title.director_id %}selected{% endif %}>
{{ director_name }}
</option>
{% endfor %}
</select><br><br>
<!-- Genre Selection -->
<label for="genre">Genre:</label>
<select id="genre" name="genre">
<option value="">Select Genre (leave blank to keep current)</option>
{% for genre_id, genre_name in genres.items() %}
<option value="{{ genre_id }}" {% if genre_id == title.listed_in %}selected{% endif %}>
{{ genre_name }}
</option>
{% endfor %}
</select><br><br>
<!-- Release Year Input -->
<label for="release_year">Release Year:</label>
<input type="number" id="release_year" name="release_year" value="{{ title.release_year }}"><br><br>
<!-- Submit and Cancel Buttons -->
<button type="submit">Update Title</button>
<a href="{{ url_for('index') }}">Cancel</a>
</form>
</body>
</html>
Menjalankan Aplikasi:
- Jalankan aplikasi Flask:
python app.py
2. Akses aplikasi di browser:
http://127.0.0.1:5000
3. Fungsi Create
Langkah 4: Visualisasi Data
File visualization.py:
- Buat file baru bernama
visualization.py.
- Tambahkan skrip berikut untuk membuat visualisasi data:
import matplotlib.pyplot as plt
import pandas as pd
from pymongo import MongoClient
# Koneksi MongoDB
client = MongoClient("mongodb://localhost:27017/")
db = client["netflix_db"]
# Koleksi yang digunakan
titles_collection = db["netflix_titles"]
countries_collection = db["netflix_titles_countries"]
categories_collection = db["netflix_titles_category"]
# Load data dari MongoDB
titles_data = pd.DataFrame(list(titles_collection.find()))
countries_data = pd.DataFrame(list(countries_collection.find()))
categories_data = pd.DataFrame(list(categories_collection.find()))
# Cek beberapa contoh data dan nama kolom
print("Data Titles:", titles_data.head())
print("Kolom Titles:", titles_data.columns)
print("Data Countries:", countries_data.head())
print("Kolom Countries:", countries_data.columns)
print("Data Categories:", categories_data.head())
print("Kolom Categories:", categories_data.columns)
# Pastikan kolom _id dan show_id memiliki tipe data yang sama
titles_data['_id'] = titles_data['_id'].astype(str)
countries_data['show_id'] = countries_data['show_id'].astype(str)
categories_data['show_id'] = categories_data['show_id'].astype(str)
# Gabungkan data berdasarkan _id
if not titles_data.empty and not countries_data.empty and not categories_data.empty:
# Gabungkan negara berdasarkan _id
titles_data = titles_data.merge(
countries_data[['show_id', 'country']], # Ambil kolom yang relevan
left_on='_id', # Gunakan '_id' untuk merge
right_on='show_id', # Gabungkan dengan 'show_id' di countries_data
how="left"
)
# Gabungkan kategori (genre) berdasarkan _id
titles_data = titles_data.merge(
categories_data[['show_id', 'listed_in']], # Ambil kolom yang relevan
left_on='_id', # Gunakan '_id' untuk merge
right_on='show_id', # Gabungkan dengan 'show_id' di categories_data
how="left"
)
# a) Berapa banyak movie dan tvshow
if "type" in titles_data.columns:
plt.figure(figsize=(8, 5))
content_type = titles_data["type"].value_counts()
content_type.plot(kind="bar", color=['#1f77b4', '#ff7f0e'])
plt.title("Jumlah Movie dan TV Show")
plt.xlabel("Type")
plt.ylabel("Count")
plt.show()
# b) Kategorikan berdasarkan genre (kolom 'genres')
if "genres" in titles_data.columns:
plt.figure(figsize=(10, 6))
genres = titles_data["genres"].dropna().str.split(", ").explode()
if not genres.empty:
genre_count = genres.value_counts().head(10)
genre_count.plot(kind="bar", color='purple')
plt.title("Top 10 Genre Terbanyak")
plt.xlabel("Genre")
plt.ylabel("Count")
plt.show()
else:
print("Tidak ada data genre untuk diproses.")
# c) Visualisasi konten berdasarkan negara
if "country_name" in titles_data.columns:
country_data = titles_data["country_name"].dropna()
if not country_data.empty:
plt.figure(figsize=(10, 6))
country_count = country_data.value_counts().head(10)
country_count.plot(kind="bar", color='green')
plt.title("Top 10 Negara dengan Konten Terbanyak")
plt.xlabel("Country")
plt.ylabel("Count")
plt.show()
else:
print("Tidak ada data negara untuk diproses.")
# d) Visualisasi negara penghasil konten terbanyak
if "country_name" in titles_data.columns:
country_content_production = titles_data.groupby("country_name").size().sort_values(ascending=False).head(10)
if not country_content_production.empty:
plt.figure(figsize=(12, 6))
country_content_production.plot(kind="bar", color='blue')
plt.title("Top 10 Negara Penghasil Konten Terbanyak")
plt.xlabel("Country")
plt.ylabel("Number of Contents Produced")
plt.show()
else:
print("Tidak ada data negara penghasil konten.")
# e) Jumlah konten dari tahun ke tahun
if "release_year" in titles_data.columns:
plt.figure(figsize=(12, 6))
release_year_count = titles_data["release_year"].dropna().value_counts().sort_index()
release_year_count.plot(kind="line", marker='o', color='red')
plt.title("Jumlah Konten per Tahun")
plt.xlabel("Year")
plt.ylabel("Count")
plt.grid()
plt.show()
# f) Berdasarkan rating
if "rating" in titles_data.columns:
plt.figure(figsize=(10, 6))
rating_count = titles_data["rating"].dropna().value_counts().head(10)
rating_count.plot(kind="bar", color='orange')
plt.title("Top 10 Rating Terbanyak di Netflix")
plt.xlabel("Rating")
plt.ylabel("Count")
plt.show()
else:
print("Salah satu koleksi kosong, periksa koleksi MongoDB Anda.")
Menjalankan Visualisasi:
- Jalankan file ini di terminal:
python visualization.py
2. Visualisasi akan ditampilkan menggunakan grafik matplotlib.
Komentar
Posting Komentar