118 lines
5.3 KiB
Python
118 lines
5.3 KiB
Python
# -*- coding: utf-8 -*-
|
|
from __future__ import print_function
|
|
|
|
from django.core.management.base import BaseCommand
|
|
from django.db import connection, transaction
|
|
from django.db.models import fields
|
|
from django.conf import settings
|
|
|
|
settings.RELOAD_CONFIG = False
|
|
import app.monkey_patch
|
|
from ... import models
|
|
import clip.models
|
|
|
|
class Command(BaseCommand):
|
|
"""
|
|
sync item sort table with current settings in site.json
|
|
"""
|
|
help = 'alter table to match itemKeys in site.json.'
|
|
args = ''
|
|
|
|
def add_arguments(self, parser):
|
|
parser.add_argument('--debug', action='store_true', dest='debug',
|
|
default=False, help='print sql commans')
|
|
|
|
def handle(self, **options):
|
|
table_name = models.ItemSort._meta.db_table
|
|
cursor = connection.cursor()
|
|
db_rows = connection.introspection.get_table_description(cursor, table_name)
|
|
db_fields = dict([(row[0], row) for row in db_rows])
|
|
db_types = dict([(row[0],
|
|
connection.introspection.data_types_reverse[row[1]]) for row in db_rows])
|
|
|
|
model_fields = ['item_id'] + [f.name for f in models.ItemSort._meta.fields]
|
|
rebuild = False
|
|
|
|
changes = []
|
|
for name in db_types:
|
|
if name not in model_fields:
|
|
sql = 'ALTER TABLE "%s" DROP COLUMN "%s"' % (table_name, name)
|
|
changes.append(sql)
|
|
|
|
for f in models.ItemSort._meta.fields:
|
|
if not f.primary_key:
|
|
name = f.name
|
|
col_type = f.db_type(connection)
|
|
if name not in db_fields:
|
|
sql = 'ALTER TABLE "%s" ADD COLUMN "%s" %s' % (table_name, name, col_type)
|
|
changes.append(sql)
|
|
sql = 'CREATE INDEX "%s_%s_idx" ON "%s" ("%s")' % (table_name, name,
|
|
table_name, name)
|
|
changes.append(sql)
|
|
rebuild = True
|
|
elif f.__class__.__name__ != db_types[name]:
|
|
sql = 'ALTER TABLE "%s" DROP COLUMN "%s"' % (table_name, name)
|
|
changes.append(sql)
|
|
sql = 'ALTER TABLE "%s" ADD COLUMN "%s" %s' % (table_name, name, col_type)
|
|
changes.append(sql)
|
|
sql = 'CREATE INDEX "%s_%s_idx" ON "%s" ("%s")' % (table_name, name,
|
|
table_name, name)
|
|
changes.append(sql)
|
|
rebuild = True
|
|
elif db_types[name] == 'CharField' and db_fields[name][3] != f.max_length:
|
|
sql = 'ALTER TABLE "%s" ALTER COLUMN "%s" TYPE %s' % (table_name, name,
|
|
col_type)
|
|
changes.append(sql)
|
|
sql = 'ALTER TABLE "%s" ALTER COLUMN "%s" %s NOT NULL' % (table_name, name,
|
|
f.null and "DROP" or "SET")
|
|
changes.append(sql)
|
|
rebuild = True
|
|
|
|
#also update clip index
|
|
table_name = clip.models.Clip._meta.db_table
|
|
db_rows = connection.introspection.get_table_description(cursor, table_name)
|
|
db_fields = dict([(row[0], row) for row in db_rows])
|
|
db_types = dict([(row[0],
|
|
connection.introspection.data_types_reverse[row[1]]) for row in db_rows])
|
|
model_fields = ['item_id', 'sort_id'] + [f.name for f in clip.models.Clip._meta.fields]
|
|
|
|
for name in db_types:
|
|
if name not in model_fields:
|
|
sql = 'ALTER TABLE "%s" DROP COLUMN "%s"' % (table_name, name)
|
|
changes.append(sql)
|
|
for f in clip.models.Clip._meta.fields:
|
|
if not f.primary_key and not isinstance(f, fields.related.ForeignKey):
|
|
name = f.name
|
|
col_type = f.db_type(connection)
|
|
if name not in db_fields:
|
|
sql = 'ALTER TABLE "%s" ADD COLUMN "%s" %s' % (table_name, name, col_type)
|
|
changes.append(sql)
|
|
sql = 'UPDATE "%s" SET "%s"=FALSE WHERE "%s" IS NULL' % (
|
|
table_name, name, name
|
|
)
|
|
changes.append(sql)
|
|
sql = 'CREATE INDEX "%s_%s_idx" ON "%s" ("%s")' % (table_name, name,
|
|
table_name, name)
|
|
changes.append(sql)
|
|
sql = 'COMMIT'
|
|
changes.append(sql)
|
|
sql = 'ALTER TABLE "%s" ALTER COLUMN "%s" SET NOT NULL' % (table_name, name)
|
|
changes.append(sql)
|
|
sql = 'BEGIN'
|
|
changes.append(sql)
|
|
if changes:
|
|
print("Updating database schema...")
|
|
for sql in changes:
|
|
if options['debug']:
|
|
print(sql)
|
|
cursor.execute(sql)
|
|
transaction.commit()
|
|
if rebuild:
|
|
print("Updating sort values...")
|
|
ids = [i['id'] for i in models.Item.objects.all().values('id')]
|
|
for id in ids:
|
|
i = models.Item.objects.get(pk=id)
|
|
if options['debug']:
|
|
print(i)
|
|
i.update_sort()
|