Ver índice de contenidos del libro

16.1. Integración con una base de datos existente

La capa de base de datos de Django genera esquemas SQL desde código Python — pero con una base de datos existente, tú ya tienes los esquemas SQL. En tal caso, necesitas crear modelos para tus tablas de la base de datos existente. Para este propósito, Django incluye una herramienta que puede generar el código del modelo leyendo el diseño de las tablas de la base de datos. Esta herramienta se llama inspectdb, y puedes llamarla ejecutando el comando manage.py inspectdb.

16.1.1. Empleo de inspectdb

La utilidad inspectdb realiza una introspección de la base de datos a la que apunta tu archivo de configuración, determina una representación del modelo que usará Django para cada una de tus tablas, e imprime el código Python del modelo a la salida estándar.

Esta es una guía de un proceso típico de integración con una base de datos existente desde cero. Las únicas suposiciones son que Django esta instalado y tienes una base de datos existente.

1. Crea un proyecto Django ejecutando django-admin.py startproject mysite (donde mysite es el nombre de tu proyecto). Usaremos mysite como nombre de proyecto en este ejemplo.

2. Edita el archivo de configuración en ese proyecto, mysite/settings.py, para decirle a Django cuáles son los parámetros de conexión a tu base de datos y cuál es su nombre. Específicamente, provee las configuraciones de DATABASE_NAME, DATABASE_ENGINE, DATABASE_USER, DATABASE_PASSWORD, DATABASE_HOST, y DATABASE_PORT. (Ten en cuenta que algunas de estas configuraciones son opcionales. Mira el Capítulo 5 para más información).

3. Crea una aplicación dentro de tu proyecto ejecutando python mysite/manage.py startapp myapp (donde myapp es el nombre de tu aplicación). Usaremos myapp como el nombre de aplicación aquí.

4. Ejecuta el comando python mysite/manage.py inspectdb. Esto examinará las tablas en la base de datos DATABASE_NAME e imprimirá para cada tabla el modelo de clase generado. Hecha una mirada a la salida para tener una idea de lo que puede hacer inspectdb.

5. Guarda la salida en el archivo models.py dentro de tu aplicación usando la redirección de salida estándar de la shell:

$ python mysite/manage.py inspectdb > mysite/myapp/models.py

6. Edita el archivo mysite/myapp/models.py para limpiar los modelos generados y realiza cualquier personalización necesaria. Te daremos algunas sugerencias para esto en la siguiente sección.

16.1.2. Limpiar los modelos generados

Como podrías esperar, la introspección de la base de datos no es perfecta, y necesitarás hacer una pequeña limpieza al código del modelo resultante. Aquí hay algunos apuntes para lidiar con los modelos generados:

1. Cada tabla de la base de datos es convertida en una clase del modelo (es decir, hay un mapeo de uno-a-uno entre las tablas de la base de datos y las clases del modelo). Esto significa que tendrás que refactorizar los modelos para tablas con relaciones muchos-a-muchos en objetos ManyToManyField.

2. Cada modelo generado tiene un atributo para cada campo, incluyendo campos de clave primaria id. Sin embargo, recuerda que Django agrega automáticamente un campo de clave primaria id si un modelo no tiene una clave primaria. Por lo tanto, querrás remover cualquier línea que se parezca a ésta:

id = models.IntegerField(primary_key=True)

No solo estas líneas son redundantes, sino que pueden causar problemas si tu aplicación agregara nuevos registros a estas tablas. El comando inspectdb no puede detectar si un campo es autoincrementado, así que está en tí cambiar esto a AutoField, si es necesario.

3. Cada tipo de campo (ej., CharField, DateField) es determinado mirando el tipo de la columna de la base de datos (ej., VARCHAR, DATE). Si inspectdb no puede mapear un tipo de columna a un tipo de campo del modelo, usará TextField e insertará el comentario Python 'This field type is a guess.' a continuación del campo en el modelo generado. Mantén un ojo en eso, y cambia el tipo de campo adecuadamente si es necesario.

Si un campo en tu base de datos no tiene un buen equivalente en Django, con seguridad puedes dejarlo fuera. La capa de modelo de Django no requiere que incluyas todos los campos de tu(s) tabla(s).

4. Si un nombre de columna de tu base de datos es una palabra reservada de Python (como pass, class o for), inspectdb agregará '_field' al nombre del atributo y establecerá el atributo db_column al nombre real del campo (ej., pass, class, o for).

Por ejemplo, si una tabla tiene una columna INT llamada for, el modelo generado tendrá un campo como este:

for_field = models.IntegerField(db_column='for')

inspectdb insertará el comentario Python 'Field renamed because it was a Python reserved word.' a continuación del campo.

5. Si tu base de datos contiene tablas que hacen referencia a otras tablas (como la mayoría de las bases de datos lo hacen), tal vez tengas que re-acomodar el orden de los modelos generados, de manera que los modelos que hacen referencia a otros modelos estén ordenados apropiadamente. Por ejemplo, si un modelo Book tiene una ForeignKey al modelo Author, el modelo Author debe ser definido antes del modelo Book. Si necesitas crear una relación en un modelo que todavía no esta definido, puedes usar el nombre del modelo, en vez del objeto modelo en sí.

6. inspectdb detecta claves primarias para PostgreSQL, MySQL y SQLite. Es decir, inserta primary_key=True donde sea necesario. Para otras bases de datos, necesitarás insertar primary_key=True para al menos un campo en cada modelo, ya que los modelos Django requieren tener un campo primary_key=True.

7. La detección de claves foráneas sólo funciona con PostgreSQL y con ciertos tipos de tablas MySQL. En otros casos, los campos de clave foránea serán generados como campos IntegerField, asumiendo que la columna de clave foránea fue una columna INT.