Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django models and legacy class integration

If I have existing classes (generated off some UML model) from legacy code, what is the best way to integrate them with the Django model classes?

I have so far considered using the Django custom fields to serialize the class and let that handle persistence. (The disadvantage of this being that other applications accessing the database directly - if it ever came to that being a requirement - would have to deserialize this field in order to access the data.)

If there is anyone that can suggest some alternatives to the aforementioned - in a way that the persistence around my existing classes can be 'swapped out' it would be greatly appreciated!

like image 486
Michael Avatar asked Nov 05 '22 20:11

Michael


1 Answers

If you are trying to move a legacy app to django, I agree with @chrisdpratt and you should try to convert your classes to Django models. It will require a large effort, so when you are ready, you can follow this trail:

  1. Create a legacy app and put your legacy code there.

    If you decide your code is not so important, and you just want to grab the data, and it is stored in an SQL based server, you can try using inspectdb to create "legacy models" that will read your data from your legacy server. I suggest to configure a second DB connection called "legacy" for this. see: https://docs.djangoproject.com/en/dev/topics/db/multi-db/

    Create a command line test script to make sure you can load your legacy classes from the database. (Make sure to set/export environment variable DJANGO_SETTINGS_MODULE from the shell prompt to run scripts from the command line or see https://docs.djangoproject.com/en/dev/ref/django-admin/?from=olddocs#running-management-commands-from-your-code ).

  2. Create your new django models in a new app ("myapp").

    Optionally, you can use inspectdb again to get a basic models automatically from a db. However, make sure you rename the models to standard Django look and feel and delete any unnecessary fields and attributes.

  3. Create a script which reads the legacy data and writes it to the new models.

  4. Migrate required logic from old classes to new classes.

You can use this as a skeleton for the script for step 3:

  # legacy/management/commands/importlegacydb.py

  from django.core.management.base import NoArgsCommand
  import myapp.models as M
  import legacy.models as L

  import sys

  write = sys.stdout.write

  def copy_fields(old, new, mapping):
      for old_key, new_key in mapping.items():
          value = getattr(old, old_key)
          if type(value) is str:
              value = value.strip()
          if type(new_key) is tuple:
              value = new_key[0](value)
              new_key = new_key[1]
          else:
              if new_key == "name":
                  value = value[0].upper() + value[1:]
          setattr(new, new_key, value)

  def import_table(old_class, new_class, mapping):
      write("importing %s " % old_class.__name__)
      lookup = {}
      l = old_class.objects.all()
      for old in l:
          new = new_class()
          copy_fields(old, new, mapping)
          new.save()
          lookup[old.id] = new.id
          write (".")
      print " Done."
      return lookup

  class Command(NoArgsCommand):
      help = "Import data from legacy db."

      def handle_noargs(self, **options):
          """
          Read data from legacy db to new db.
          """
          print "Importing legacy data"

          import_table(L.X, M.X, { 'old_field' : 'new_field', 'old_field2' : 'new_field2'})
          import_table(L.Y, M.Y, { 'old_field' : 'new_field'})

          print "Done."
like image 135
Udi Avatar answered Nov 13 '22 17:11

Udi