What are the best practices for working with Legacy Database in Django?

Asked

Viewed 1,434 times

6

I have a legacy database and would like to know what good practices for table names, or tips on how to use inflections (like in Rails) for Django in the latest version.

  • 5

    Welcome to the site, user1320! Would it be possible to edit your question to make it clearer and more specific? For example, do you want to know if Django has any standard table naming, or "good practice" in general (which would be a little broad)? I suggest showing examples of your legacy base nomenclature, and the type of result you want to achieve. Thank you!

2 answers

9

The "best practice" would be to let Django himself assign the names of the tables and fields, but that doesn’t apply to your case, right? If you have a legacy database, you can keep its structure as it is - no need to make changes (except in one case, as I will explain below).

Automatically creating templates

Django has a tool called inspectdb to facilitate the creation of your models, when you already have a database ready. You can use it to "start" but generally adaptations will be required.

Models managed or not

Django has a tool called syncdb (in future versions, will be made obsolete and replaced by migrate) that takes care of the creation of tables, their fields and indexes automatically, from the defined models. In future versions, it will also feature schema migration tools. When you use such a template, it is called managed (Managed).

If you don’t want to make use of this feature - creating and keeping your tables another way - you can mark it as unmanaged (Unmanaged). This is done through an attribute in the class Meta of your model:

class Pessoa(models.Model):
    id = models.IntegerField(primary_key=True)
    primeiro_nome = models.CharField(max_length=70)
    class Meta:
        managed = False
        db_table = 'nome_da_tabela'

Note that the fact that the table already exists does not automatically mean that you need an unmanaged model - you can take the table the way it is, and let Django help you with future schema migrations. This is your choice.

Table and column names

If you do not specify anything, Django will search/create tables and columns with a standardized name, inferred from the name of your app and the names of your models and fields. If you need to specify them manually, just use db_table (as already shown in the example above) for the table name and/or db_column for the column names:

class Pessoa(models.Model):
    id = models.IntegerField(primary_key=True, db_column="pessoa_id")
    primeiro_nome = models.CharField(max_length=70, db_column="nome")
    class Meta:
        managed = False
        db_table = 'nome_da_tabela'

There are also other options to customize the integration with DB (such as db_index and db_tablespace), see the Django documentation for more details.

Every table needs a primary key

This is the only case where perhaps an adaptation to their tables is necessary. For Django’s ORM to work, every table must have a primary key, and that primary key must be simple (i.e. a single column - cannot be a composite key). If you do not specify anything, Django will assume that you have a numeric field called id. If you need to specify, just use the property primary_key, as already demonstrated in the previous examples.

Whenever possible, use the table name in the singular

It took me a little while to figure out what "inflections" were, but from what I understand is that functionality where Rails automatically "pluralizes" the table name for you, right? There is nothing like this in Django, the default behavior is to use the name in the singular even for the tables (and in my opinion this is the ideal - pluralizing introduces an unnecessary complication to solve a problem that does not exist).

If you really need names are in the plural, use db_table manually as explained above.

0

Database views can also be used in your models, so include in inspectdb the --include-views parameter, however, provide the inclusion of a primary key in your views, as @mgibsonbr already mentioned, are necessary.

CREATE OR REPLACE VIEW ... AS
   id ROW_NUMBER() OVER(),
   field1 ...
   fieldn ...

Browser other questions tagged

You are not signed in. Login or sign up in order to post.