Database
 sql >> Teknologi Basis Data >  >> RDS >> Database

Migrasi Django:Sebuah Primer

Tonton Sekarang Tutorial ini memiliki kursus video terkait yang dibuat oleh tim Real Python. Tonton bersama dengan tutorial tertulis untuk memperdalam pemahaman Anda:Django Migration 101

Sejak versi 1.7, Django telah datang dengan dukungan bawaan untuk migrasi basis data. Di Django, migrasi basis data biasanya berjalan seiring dengan model:kapan pun Anda membuat kode model baru, Anda juga menghasilkan migrasi untuk membuat tabel yang diperlukan dalam basis data. Namun, migrasi dapat melakukan lebih banyak hal.

Anda akan mempelajari bagaimana Django Migration bekerja dan bagaimana Anda bisa mendapatkan hasil maksimal dari mereka selama empat artikel dan satu video:

  • Bagian 1:Django Migration:A Primer (artikel saat ini)
  • Bagian 2:Menggali Migrasi Lebih Dalam
  • Bagian 3:Migrasi Data
  • Video:Django 1.7 Migrasi - primer

Dalam artikel ini, Anda akan merasa nyaman dengan migrasi Django dan mempelajari yang berikut:

  • Cara membuat tabel database tanpa menulis SQL
  • Cara memodifikasi database secara otomatis setelah Anda mengubah model
  • Cara mengembalikan perubahan yang dibuat ke database Anda

Bonus Gratis: Klik di sini untuk mendapatkan akses ke Panduan Sumber Daya Pembelajaran Django (PDF) gratis yang menunjukkan kepada Anda tip dan trik serta perangkap umum yang harus dihindari saat membangun aplikasi web Python + Django.


Masalah Yang Dipecahkan Migrasi

Jika Anda baru mengenal Django atau pengembangan web secara umum, Anda mungkin tidak familiar dengan konsep migrasi basis data, dan mungkin tidak tampak jelas mengapa mereka merupakan ide yang bagus.

Pertama, mari kita definisikan beberapa istilah dengan cepat untuk memastikan semua orang berada di halaman yang sama. Django dirancang untuk bekerja dengan basis data relasional, disimpan dalam sistem manajemen basis data relasional seperti PostgreSQL, MySQL, atau SQLite.

Dalam database relasional, data diatur dalam tabel. Sebuah tabel database memiliki sejumlah kolom, tetapi dapat memiliki sejumlah baris. Setiap kolom memiliki tipe data tertentu, seperti string dengan panjang maksimum tertentu atau bilangan bulat positif. Deskripsi semua tabel dengan kolomnya dan tipe datanya masing-masing disebut skema database.

Semua sistem basis data yang didukung oleh Django menggunakan bahasa SQL untuk membuat, membaca, memperbarui dan menghapus data dalam basis data relasional. SQL juga digunakan untuk membuat, mengubah, dan menghapus tabel database itu sendiri.

Bekerja secara langsung dengan SQL bisa sangat rumit, jadi untuk membuat hidup Anda lebih mudah, Django hadir dengan pemetaan objek-relasional, atau disingkat ORM. ORM memetakan database relasional ke dunia pemrograman berorientasi objek. Alih-alih mendefinisikan tabel database dalam SQL, Anda menulis model Django dengan Python. Model Anda menentukan bidang basis data, yang sesuai dengan kolom di tabel basis datanya.

Berikut adalah contoh bagaimana kelas model Django dipetakan ke tabel database:

Tetapi hanya mendefinisikan kelas model dalam file Python tidak membuat tabel database secara ajaib muncul entah dari mana. Membuat tabel database untuk menyimpan model Django Anda adalah tugas dari migrasi database. Selain itu, setiap kali Anda membuat perubahan pada model Anda, seperti menambahkan bidang, database juga harus diubah. Migrasi juga menanganinya.

Berikut adalah beberapa cara migrasi Django membuat hidup Anda lebih mudah.


Membuat Perubahan Basis Data Tanpa SQL

Tanpa migrasi, Anda harus terhubung ke database dan mengetikkan sekumpulan perintah SQL atau menggunakan alat grafis seperti PHPMyAdmin untuk memodifikasi skema database setiap kali Anda ingin mengubah definisi model.

Di Django, migrasi terutama ditulis dalam Python, jadi Anda tidak perlu mengetahui SQL apa pun kecuali Anda memiliki kasus penggunaan yang benar-benar canggih.



Menghindari Pengulangan

Membuat model dan kemudian menulis SQL untuk membuat tabel database karena itu akan berulang.

Migrasi dihasilkan dari model Anda, memastikan Anda tidak mengulanginya sendiri.



Memastikan Definisi Model dan Skema Basis Data Tersinkronisasi

Biasanya, Anda memiliki beberapa contoh database, misalnya satu database untuk setiap pengembang di tim Anda, database untuk pengujian, dan database dengan data langsung.

Tanpa migrasi, Anda harus melakukan perubahan skema apa pun pada setiap database Anda, dan Anda harus melacak perubahan mana yang telah dilakukan pada database mana.

Dengan Django Migrations, Anda dapat dengan mudah menyimpan banyak basis data sinkron dengan model Anda.



Melacak Perubahan Skema Basis Data di Kontrol Versi

Sistem kontrol versi, seperti Git, sangat baik untuk kode, tetapi tidak untuk skema database.

Karena migrasi adalah Python biasa di Django, Anda dapat menempatkannya dalam sistem kontrol versi sama seperti bagian kode lainnya.

Sekarang, semoga Anda yakin bahwa migrasi adalah alat yang berguna dan kuat. Mari mulai belajar cara melepaskan kekuatan itu.




Menyiapkan Proyek Django

Sepanjang tutorial ini, Anda akan mengerjakan aplikasi pelacak Bitcoin sederhana sebagai proyek contoh.

Langkah pertama adalah menginstal Django. Inilah cara Anda melakukannya di Linux atau macOS X menggunakan lingkungan virtual:

$ python3 -m venv env
$ source env/bin/activate
(env) $ pip install "Django==2.1.*"
...
Successfully installed Django-2.1.3

Sekarang Anda telah membuat lingkungan virtual baru dan mengaktifkannya, serta menginstal Django di lingkungan virtual itu.

Perhatikan bahwa pada Windows, Anda akan menjalankan env/bin/activate.bat alih-alih source env/bin/activate untuk mengaktifkan lingkungan virtual Anda.

Agar lebih mudah dibaca, contoh konsol tidak akan menyertakan (env) bagian dari prompt mulai sekarang.

Dengan Django terinstal, Anda dapat membuat proyek menggunakan perintah berikut:

$ django-admin.py startproject bitcoin_tracker
$ cd bitcoin_tracker
$ python manage.py startapp historical_data

Ini memberi Anda proyek sederhana dan aplikasi bernama historical_data . Anda sekarang harus memiliki struktur direktori ini:

bitcoin_tracker/
|
├── bitcoin_tracker/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
|
├── historical_data/
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations/
│   │   └── __init__.py
|   |
│   ├── models.py
│   ├── tests.py
│   └── views.py
|
└── manage.py

Di dalam bitcoin_tracker direktori, ada dua sub-direktori:bitcoin_tracker untuk file di seluruh proyek dan historical_data berisi file untuk aplikasi yang Anda buat.

Sekarang, untuk membuat model, tambahkan kelas ini di historical_data/models.py :

class PriceHistory(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    price = models.DecimalField(max_digits=7, decimal_places=2)
    volume = models.PositiveIntegerField()

Ini adalah model dasar untuk melacak harga Bitcoin.

Juga, jangan lupa untuk menambahkan aplikasi yang baru dibuat ke settings.INSTALLED_APPS . Buka bitcoin_tracker/settings.py dan tambahkan historical_data ke daftar INSTALLED_APPS , seperti ini:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'historical_data',
]

Pengaturan lain baik-baik saja untuk proyek ini. Tutorial ini mengasumsikan bahwa proyek Anda dikonfigurasi untuk menggunakan database SQLite, yang merupakan default.



Membuat Migrasi

Dengan model yang dibuat, hal pertama yang perlu Anda lakukan adalah membuat migrasi untuknya. Anda dapat melakukannya dengan perintah berikut:

$ python manage.py makemigrations historical_data
Migrations for 'historical_data':
  historical_data/migrations/0001_initial.py
    - Create model PriceHistory

Catatan: Menentukan nama aplikasi, historical_data , adalah opsional. Meninggalkannya akan membuat migrasi untuk semua aplikasi.

Ini membuat file migrasi yang menginstruksikan Django tentang cara membuat tabel database untuk model yang didefinisikan dalam aplikasi Anda. Mari kita lihat lagi pohon direktori:

bitcoin_tracker/
|
├── bitcoin_tracker/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
|
├── historical_data/
│   ├── migrations/
│   │   ├── 0001_initial.py
│   │   └── __init__.py
|   |
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
|
├── db.sqlite3
└── manage.py

Seperti yang Anda lihat, migrations direktori sekarang berisi file baru:0001_initial.py .

Catatan: Anda mungkin memperhatikan bahwa menjalankan makemigrations perintah juga membuat file db.sqlite3 , yang berisi database SQLite Anda.

Saat Anda mencoba mengakses file database SQLite3 yang tidak ada, file tersebut akan dibuat secara otomatis.

Perilaku ini unik untuk SQLite3. Jika Anda menggunakan backend database lain seperti PostgreSQL atau MySQL, Anda harus membuat database sendiri sebelum menjalankan makemigrations .

Anda dapat mengintip database dengan dbshell perintah manajemen. Di SQLite, perintah untuk membuat daftar semua tabel hanyalah .tables :

$ python manage.py dbshell
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
sqlite> .tables
sqlite>

Basis datanya masih kosong. Itu akan berubah ketika Anda menerapkan migrasi. Ketik .quit untuk keluar dari shell SQLite.



Menerapkan Migrasi

Anda sekarang telah membuat migrasi, tetapi untuk benar-benar membuat perubahan apa pun dalam database, Anda harus menerapkannya dengan perintah manajemen migrate :

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, historical_data, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying historical_data.0001_initial... OK
  Applying sessions.0001_initial... OK

Ada banyak hal yang terjadi di sini! Menurut output, migrasi Anda telah berhasil diterapkan. Tapi dari mana semua migrasi lainnya berasal?

Ingat pengaturan INSTALLED_APPS ? Beberapa aplikasi lain yang terdaftar di sana juga dilengkapi dengan migrasi, dan migrate perintah manajemen menerapkan migrasi untuk semua aplikasi yang diinstal secara default.

Lihat lagi databasenya:

$ python manage.py dbshell
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
sqlite> .tables
auth_group                    django_admin_log
auth_group_permissions        django_content_type
auth_permission               django_migrations
auth_user                     django_session
auth_user_groups              historical_data_pricehistory
auth_user_user_permissions
sqlite>

Sekarang ada beberapa tabel. Nama mereka memberi Anda gambaran tentang tujuan mereka. Migrasi yang Anda buat pada langkah sebelumnya telah membuat historical_data_pricehistory meja. Mari kita periksa menggunakan .schema perintah:

sqlite> .schema --indent historical_data_pricehistory
CREATE TABLE IF NOT EXISTS "historical_data_pricehistory"(
  "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
  "date" datetime NOT NULL,
  "price" decimal NOT NULL,
  "volume" integer unsigned NOT NULL
);

.schema perintah mencetak CREATE pernyataan yang akan Anda jalankan untuk membuat tabel. Parameter --indent memformatnya dengan baik. Bahkan jika Anda tidak terbiasa dengan sintaks SQL, Anda dapat melihat bahwa skema historical_data_pricehistory tabel mencerminkan bidang PriceHistory model.

Ada kolom untuk setiap kolom dan kolom tambahan id untuk kunci utama, yang Django buat secara otomatis kecuali jika Anda secara eksplisit menetapkan kunci utama dalam model Anda.

Inilah yang terjadi jika Anda menjalankan migrate perintah lagi:

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, historical_data, sessions
Running migrations:
  No migrations to apply.

Tidak ada apa-apa! Django mengingat migrasi mana yang telah diterapkan dan tidak mencoba menjalankannya kembali.

Perlu dicatat bahwa Anda juga dapat membatasi migrations perintah manajemen ke satu aplikasi:

$ python manage.py migrate historical_data
Operations to perform:
 Apply all migrations: historical_data
Running migrations:
 No migrations to apply.

Seperti yang Anda lihat, Django sekarang hanya menerapkan migrasi untuk historical_data aplikasi.

Saat Anda menjalankan migrasi untuk pertama kalinya, sebaiknya terapkan semua migrasi untuk memastikan database Anda berisi tabel yang diperlukan untuk fitur yang mungkin Anda anggap remeh, seperti autentikasi pengguna dan sesi.



Mengubah Model

Model Anda tidak kaku. Model Anda akan berubah saat proyek Django Anda memperoleh lebih banyak fitur. Anda dapat menambahkan atau menghapus bidang atau mengubah jenis dan opsinya.

Saat Anda mengubah definisi model, tabel database yang digunakan untuk menyimpan model ini juga harus diubah. Jika definisi model Anda tidak cocok dengan skema basis data Anda saat ini, kemungkinan besar Anda akan mengalami django.db.utils.OperationalError .

Jadi bagaimana Anda mengubah tabel database? Dengan membuat dan menerapkan migrasi.

Saat menguji pelacak Bitcoin Anda, Anda menyadari bahwa Anda melakukan kesalahan. Orang-orang menjual pecahan Bitcoin, jadi kolom volume harus dari jenis DecimalField bukannya PositiveIntegerField .

Mari kita ubah modelnya menjadi seperti ini:

class PriceHistory(models.Model):
    date = models.DateTimeField(auto_now_add=True)
    price = models.DecimalField(max_digits=7, decimal_places=2)
    volume = models.DecimalField(max_digits=7, decimal_places=3)

Tanpa migrasi, Anda harus mengetahui sintaks SQL untuk mengubah PositiveIntegerField menjadi DecimalField . Untungnya, Django akan menanganinya untuk Anda. Katakan saja untuk melakukan migrasi:

$ python manage.py makemigrations
Migrations for 'historical_data':
  historical_data/migrations/0002_auto_20181112_1950.py
    - Alter field volume on pricehistory

Catatan: Nama file migrasi (0002_auto_20181112_1950.py ) didasarkan pada waktu saat ini dan akan berbeda jika Anda mengikuti sistem Anda.

Sekarang Anda menerapkan migrasi ini ke database Anda:

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, historical_data, sessions
Running migrations:
  Applying historical_data.0002_auto_20181112_1950... OK

Migrasi telah berhasil diterapkan, jadi Anda dapat menggunakan dbshell untuk memverifikasi bahwa perubahan tersebut berpengaruh:

$ python manage.py dbshell
SQLite version 3.19.3 2017-06-27 16:48:08
Enter ".help" for usage hints.
sqlite> .schema --indent historical_data_pricehistory
CREATE TABLE IF NOT EXISTS "historical_data_pricehistory" (
  "id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
  "date" datetime NOT NULL,
  "price" decimal NOT NULL,
  "volume" decimal NOT NULL
);

Jika Anda membandingkan skema baru dengan skema yang Anda lihat sebelumnya, Anda akan melihat bahwa jenis volume kolom telah berubah dari integer ke decimal untuk mencerminkan perubahan volume bidang dalam model dari PositiveIntegerField ke DecimalField .



Mendaftarkan Migrasi

Jika Anda ingin mengetahui migrasi apa yang ada dalam proyek Django, Anda tidak perlu menggali melalui migrations direktori aplikasi yang Anda instal. Anda dapat menggunakan showmigrations perintah:

$ ./manage.py showmigrations
admin
 [X] 0001_initial
 [X] 0002_logentry_remove_auto_add
 [X] 0003_logentry_add_action_flag_choices
auth
 [X] 0001_initial
 [X] 0002_alter_permission_name_max_length
 [X] 0003_alter_user_email_max_length
 [X] 0004_alter_user_username_opts
 [X] 0005_alter_user_last_login_null
 [X] 0006_require_contenttypes_0002
 [X] 0007_alter_validators_add_error_messages
 [X] 0008_alter_user_username_max_length
 [X] 0009_alter_user_last_name_max_length
contenttypes
 [X] 0001_initial
 [X] 0002_remove_content_type_name
historical_data
 [X] 0001_initial
 [X] 0002_auto_20181112_1950
sessions
 [X] 0001_initial

Ini mencantumkan semua aplikasi dalam proyek dan migrasi yang terkait dengan setiap aplikasi. Juga, itu akan menempatkan X besar di sebelah migrasi yang telah diterapkan.

Untuk contoh kecil kami, showmigrations perintah tidak terlalu menarik, tetapi berguna ketika Anda mulai bekerja pada basis kode yang ada atau bekerja dalam tim di mana Anda bukan satu-satunya orang yang menambahkan migrasi.



Membatalkan Penerapan Migrasi

Sekarang Anda tahu cara membuat perubahan pada skema database Anda dengan membuat dan menerapkan migrasi. Pada titik tertentu, Anda mungkin ingin membatalkan perubahan dan beralih kembali ke skema database sebelumnya karena Anda:

  • Ingin menguji migrasi yang ditulis seorang rekan
  • Sadari bahwa perubahan yang Anda buat adalah ide yang buruk
  • Bekerja pada beberapa fitur dengan perubahan database yang berbeda secara paralel
  • Ingin memulihkan cadangan yang dibuat saat database masih memiliki skema lama

Untungnya, migrasi tidak harus menjadi jalan satu arah. Dalam banyak kasus, efek migrasi dapat dibatalkan dengan membatalkan penerapan migrasi. Untuk membatalkan permohonan migrasi, Anda harus memanggil migrate dengan nama aplikasi dan nama migrasi sebelum migrasi yang ingin Anda batalkan.

Jika Anda ingin mengembalikan migrasi 0002_auto_20181112_1950 di historical_data . Anda aplikasi, Anda harus melewati 0001_initial sebagai argumen untuk migrations perintah:

$ python manage.py migrate historical_data 0001_initial
Operations to perform:
  Target specific migration: 0001_initial, from historical_data
Running migrations:
  Rendering model states... DONE
  Unapplying historical_data.0002_auto_20181112_1950... OK

Migrasi belum diterapkan, artinya perubahan pada database telah dibalik.

Membatalkan penerapan migrasi tidak menghapus file migrasinya. Lain kali Anda menjalankan migrate perintah, migrasi akan diterapkan lagi.

Perhatian: Jangan bingung membatalkan penerapan migrasi dengan operasi pembatalan yang biasa Anda lakukan dari editor teks favorit Anda.

Tidak semua operasi database dapat sepenuhnya dikembalikan. Jika Anda menghapus bidang dari model, membuat migrasi, dan menerapkannya, Django akan menghapus masing-masing kolom dari basis data.

Membatalkan penerapan migrasi tersebut akan membuat ulang kolom, tetapi tidak akan mengembalikan data yang disimpan di kolom itu!

Saat Anda berurusan dengan nama migrasi, Django menghemat beberapa penekanan tombol dengan tidak memaksa Anda untuk mengeja seluruh nama migrasi. Hanya perlu nama yang cukup untuk mengidentifikasinya secara unik.

Pada contoh sebelumnya, itu sudah cukup untuk menjalankan python manage.py migrate historical_data 0001 .



Menamai Migrasi

Dalam contoh di atas, Django muncul dengan nama untuk migrasi berdasarkan cap waktu—sesuatu seperti *0002_auto_20181112_1950 . Jika Anda tidak puas dengan itu, Anda dapat menggunakan --name parameter untuk memberikan nama khusus (tanpa .py ekstensi).

Untuk mencobanya, Anda harus menghapus migrasi lama terlebih dahulu. Anda telah membatalkan penerapannya, sehingga Anda dapat menghapus file dengan aman:

$ rm historical_data/migrations/0002_auto_20181112_1950.py

Sekarang Anda dapat membuatnya kembali dengan nama yang lebih deskriptif:

$ ./manage.py makemigrations historical_data --name switch_to_decimals

Ini akan membuat migrasi yang sama seperti sebelumnya kecuali dengan nama baru 0002_switch_to_decimals .



Kesimpulan

Anda membahas sedikit dasar dalam tutorial ini dan mempelajari dasar-dasar migrasi Django.

Untuk rekap, langkah-langkah dasar untuk menggunakan migrasi Django terlihat seperti ini:

  1. Membuat atau memperbarui model
  2. Jalankan ./manage.py makemigrations <app_name>
  3. Jalankan ./manage.py migrate untuk memigrasikan semuanya atau ./manage.py migrate <app_name> untuk memigrasikan aplikasi individual
  4. Ulangi seperlunya

Itu dia! Alur kerja ini akan berfungsi sebagian besar waktu, tetapi jika hal-hal tidak berjalan seperti yang diharapkan, Anda juga tahu cara mendaftar dan membatalkan migrasi.

Jika sebelumnya Anda membuat dan memodifikasi tabel database Anda dengan SQL tulisan tangan, Anda sekarang menjadi jauh lebih efisien dengan mendelegasikan pekerjaan ini ke migrasi Django.

Dalam tutorial berikutnya dalam seri ini, Anda akan menggali lebih dalam topik dan mempelajari bagaimana Django Migration bekerja di bawah tenda.

Bonus Gratis: Klik di sini untuk mendapatkan akses ke Panduan Sumber Daya Pembelajaran Django (PDF) gratis yang menunjukkan kepada Anda tip dan trik serta perangkap umum yang harus dihindari saat membangun aplikasi web Python + Django.

Semangat!



Video



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Penyaringan Tabel di Meja Kerja IRI

  2. Tutorial SSIS Untuk Pemula:Mengapa, Apa dan Bagaimana?

  3. Prisma, cara menghapus database

  4. Paket Berbeda untuk Server Identik

  5. Cara menghapus data dari Elastisearch