Opened 4 years ago

Closed 4 years ago

Last modified 3 years ago

#23159 closed Cleanup/optimization (wontfix)

There should be a way to exclude certain fields from migrations

Reported by: Federico Capoano Owned by: nobody
Component: Migrations Version: 1.7-rc-2
Severity: Release blocker Keywords: migrations
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

In django 1.7 IMHO there should be a way to tell django to ignore certain fields from the migration procedure.

This would allow greater flexibility in creating.

At the moment (django 1.7 rc2) the only way to tell django to skip a certain field from a migration is to declare it a relation or make it subclass OrderWrt.

Change History (9)

comment:1 in reply to:  description Changed 4 years ago by Simon Charette

Replying to nemesisdesign:

In django 1.7 IMHO there should be a way to tell django to ignore certain fields from the migration procedure.

This would allow greater flexibility in creating.

Hi @nemesisdesign,

Could you provide a use case for this feature?

I'm asking because I cannot think of one myself and thus I'm not convinced it should be added to the migration framework.

comment:2 Changed 4 years ago by Federico Capoano

The reason is that it is possible to have fields which do not correspond to a real database column but to some more complex machinery, like a key value store (HStore), but still want to take advantage of standard django features like the django-admin, model validation or django-rest-framework.
Unfortunately virtual fields are not really supported yet, so to workaround this limitation I found it useful to create virtual fields which just return None in the db_type method and have the column attribute set to None.
If that worked in djagno 1.6, it doesn't play well in django 1.7 as there's no way to tell the migration framework to skip fields unless using this as a base class:
https://github.com/django/django/blob/master/django/db/models/fields/proxy.py which is not very clean.

I propose that instead of hardcoding OrderWrt in this loop here:
https://github.com/django/django/blob/master/django/db/migrations/state.py#L170
We have some property on the field, like self.migrate, that tells that loop if it has to skip or not.

comment:3 Changed 4 years ago by Federico Capoano

Alternatively, if adding a new attribute is time-consuming and doesn't add much value, we can ensure backward compatiblity by testing for the column attribute on the field:

if isinstance(field, OrderWrt):
    continue
# these two lines maximize compatibility with existing apps that set the column attribute to None
if field.column is None:
    continue

The column attribute is used in the options API to determine if a field should be considered as concrete or not:
https://github.com/django/django/blob/master/django/db/models/options.py#L315

So it makes sense to skip non-concrete fields in the migrations framework too.

Otherwise IMHO the way django 1.7 would treat these non-concrete fields would be really inconsistent (sad). It slighlty differs already from django models than django model forms (which is daunting), and it would differ in a new way in the migration framework (not nice at all).

I hope you can consider these points in this new awsome feature that is the migration framework. I'm pretty sure one of these two solutions won't break existing tests and would ensure maximum compatibility, hence benefit future django versions lot.

comment:4 Changed 4 years ago by Federico Capoano

Has patch: set

comment:5 Changed 4 years ago by Tim Graham

Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted
Type: UncategorizedCleanup/optimization

comment:6 Changed 4 years ago by Federico Capoano

should I send the pull request to the master branch in order for jenkins to run the entire test suite on it?

comment:7 Changed 4 years ago by Andrew Godwin

Resolution: wontfix
Status: newclosed

Alas, migrations need to include all fields, concrete or not, much in the same way as they include all field arguments, concrete or not.

Just ensure that db_type is None - the SchemaEditor will realise you're a virtual column and ignore you. Closing as WONTFIX, since the particular request of this ticket (to exclude those fields from migration files) is against the design of migrations.

If there's genuinely a problem where Django crashes with a custom field that has db_type set to None while running migrations, then please open a ticket for _that_ issue, as that would need fixing.

comment:8 Changed 4 years ago by Kerin Cosford

I've run into a similar problem, which is preventing us from upgrading to Django 1.7.

We've defined a custom field type that maps a single field to multiple db columns:

https://github.com/ministryofjustice/cla_common/blob/develop/cla_common/money_interval/fields.py#L65

Running makemigrations generates a field for each custom field, and a field for each derived DB field, so migrate fails with duplicate column declarations. I've tried declaring db_type as None on the custom field, to no effect, and subclassing OrderWrt doesn't work either, as our models containing multiple instances of this field, which generates an _order field clash error. So short of rewriting our custom field to not use multiple DB fields, I'm not sure what the solution to this kind of pattern is.

comment:9 in reply to:  description Changed 3 years ago by Federico Capoano

It would be useful peraphs to take a look at this issue (still regarding virtual fields):
https://github.com/djangonauts/django-hstore/issues/103

Setting the db_type as None still doesn't work in all cases.

Note: See TracTickets for help on using tickets.
Back to Top