2015-08-05 18 views
15

Trong Django, có cách nào dễ dàng để kiểm tra xem tất cả di chuyển cơ sở dữ liệu đã được chạy chưa? Tôi đã tìm thấy manage.py migrate --list, cung cấp cho tôi thông tin tôi muốn, nhưng định dạng không phải là rất dễ đọc.Kiểm tra di chuyển Django đang chờ xử lý

Đối với ngữ cảnh: Tôi có một tập lệnh không nên bắt đầu chạy cho đến khi cơ sở dữ liệu được di chuyển. Vì nhiều lý do, sẽ rất khó để gửi tín hiệu từ quá trình đang chạy di chuyển. Vì vậy, tôi muốn có kịch bản của tôi định kỳ kiểm tra cơ sở dữ liệu để xem nếu tất cả các di chuyển đã chạy.

+0

bạn có đang chạy tập lệnh tự động để kiểm tra di chuyển như vải không? – Praneeth

+1

http://stackoverflow.com/a/8491203/4325513 – Praneeth

Trả lời

20

Shell

Giải pháp đơn giản duy nhất tôi đã tìm thấy cho đến nay đang chạy

./manage.py showmigrations | grep '\[ \]' 

đó sẽ ra một chuỗi rỗng trong trường hợp tất cả các cuộc di cư đã được áp dụng.

Tuy nhiên, nó được gắn chặt với định dạng đầu ra.

Python

Tôi đã kiểm tra mã nguồn của migrate lệnh và nó có vẻ như điều này sẽ làm các trick:

from django.db.migrations.executor import MigrationExecutor 
from django.db import connections, DEFAULT_DB_ALIAS 


def is_database_synchronized(database): 
    connection = connections[database] 
    connection.prepare_database() 
    executor = MigrationExecutor(connection) 
    targets = executor.loader.graph.leaf_nodes() 
    return False if executor.migration_plan(targets) else True 

# Usage example. 
if is_database_synchronized(DEFAULT_DB_ALIAS): 
    # All migrations have been applied. 
    pass 
else: 
    # Unapplied migrations found. 
    pass 
+2

Trong Django 1,7 hoặc lên, bạn có thể sử dụng: 'showmigrations ./manage --list' hoặc ' ./manage showmigrations --plan' – NeoMorfeo

2

Sử dụng mã @Ernest, tôi đã viết một manage_custom.py cho sự di cư cấp phát . Bạn có thể lấy danh sách di chuyển đang chờ xử lý cũng di chuyển các lần di chuyển đang chờ xử lý này (chỉ), do đó tiết kiệm thời gian của bạn.

manage_custom.py

__author__ = "Parag Tyagi" 

# set environment 
import os 
import sys 
import django 
sys.path.append('../') 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings') 
django.setup() 

from django.core.management import execute_from_command_line 
from django.db import DEFAULT_DB_ALIAS, connections 
from django.db.migrations.executor import MigrationExecutor 


class Migration(object): 
    """ 
    A custom manage.py file for managing pending migrations (only) 
    """ 

    def __init__(self, migrate_per_migration_id=False): 
     """ 
     :param migrate_per_migration_id: Setting this to `True` will migrate each pending migration of any 
     particular app individually. `False` will migrate the whole app at a time. 

     You can add more arguments (viz. showmigrations, migrate) by defining the argument with prefix as 'ARGV_' 
     and create its functionality accordingly. 
     """ 
     self.ARG_PREFIX = 'ARGV_' 
     self.MIGRATE_PER_MIGRATION_ID = migrate_per_migration_id 
     self.ARGV_showmigrations = False 
     self.ARGV_migrate = False 

    @staticmethod 
    def get_pending_migrations(database): 
     """ 
     :param database: Database alias 
     :return: List of pending migrations 
     """ 
     connection = connections[database] 
     connection.prepare_database() 
     executor = MigrationExecutor(connection) 
     targets = executor.loader.graph.leaf_nodes() 
     return executor.migration_plan(targets) 

    def check_arguments(self, args): 
     """ 
     Method for checking arguments passed while running the command 
     :param args: Dictionary of arguments passed while running the script file 
     :return: Set the argument variable ('ARGV_<argument>') to True if found else terminate the script 
     """ 
     required_args = filter(None, [var.split(self.ARG_PREFIX)[1] if var.startswith(self.ARG_PREFIX) 
             else None for var in self.__dict__.keys()]) 
     if any(k in args for k in required_args): 
      for arg in required_args: 
       if arg in args: 
        setattr(self, '{}{}'.format(self.ARG_PREFIX, arg), True) 
        break 
     else: 
      print ("Please pass argument: {}" 
        "\ne.g. python manage_custom.py {}".format(required_args, required_args[0])) 
      sys.exit() 

    def do_migration(self): 
     """ 
     Migrates all the pending migrations (if any) 
     """ 
     pending_migrations = self.get_pending_migrations(DEFAULT_DB_ALIAS) 
     if pending_migrations: 
      done_app = [] 
      for mig in pending_migrations: 
       app, migration_id = str(mig[0]).split('.') 
       commands = ['manage.py', 'migrate'] + ([app, migration_id] if self.MIGRATE_PER_MIGRATION_ID else [app]) 
       if self.ARGV_migrate and (app not in done_app or self.MIGRATE_PER_MIGRATION_ID): 
        execute_from_command_line(commands) 
        done_app.append(app) 
       elif self.ARGV_showmigrations: 
        print (str(mig[0])) 
     else: 
      print ("No pending migrations") 


if __name__ == '__main__': 
    args = sys.argv 
    migration = Migration() 
    migration.check_arguments(args) 
    migration.do_migration() 

Cách sử dụng:

# below command will show all pending migrations 
python manage_custom.py showmigrations 

# below command will migrate all pending migrations 
python manage_custom.py migrate 

PS: Hãy môi trường thiết lập theo cấu trúc dự án của bạn.

6

Cố gắng,

python manage.py migrate --list | grep "\[ \]\|^[a-z]" | grep "[ ]" -B 1 

lợi nhuận,

<app_1> 
[ ] 0001_initial 
[ ] 0002_auto_01201244 
[ ] 0003_auto_12334333 

<app_2> 
[ ] 0031_auto_12344544 
[ ] 0032_auto_45456767 
[ ] 0033_auto_23346566 

<app_3> 
[ ] 0008_auto_3446677 


Cập nhật:

Nếu bạn đã cập nhật Django để 1.11, sử dụng dưới lệnh,

python manage.py showmigrations | grep '\[ \]\|^[a-z]' | grep '[ ]' -B 1 
0

1.10 ghi chú phát hành:

Các makemigrations --check tùy chọn mới làm cho lối ra lệnh với một tình trạng khác không khi thay đổi mô hình mà không di cư được phát hiện.

Các vấn đề liên quan