On Thu, Jun 7, 2012 at 3:56 PM, Anssi Kääriäinen
<anssi.kaariai...@thl.fi> wrote:
> On Jun 7, 8:17 pm, Andrew Godwin <and...@aeracode.org> wrote:
>> Hi everyone,
>>
>> As part of my planning for adding schema alteration/migrations into
>> Django proper, I need to make a few changes to Fields to allow for
>> better serialisation of model definitions (pretty much a requirement for
>> any change-detecting migrations system).
>>
>> In particular, I propose:
>>
>>  - Requiring that all fields expose a method which says how to
>> reconstruct them.
>>
>> Essentially, it returns the positional and keyword arguments you would
>> have to pass into the constructor to make the field again (as there's no
>> way to get them directly). For those familiar with south_field_triple,
>> it would be a bit like that.
>
> Is the reason for this to be able to track changes to field by
> checking if its init arguments have changed? Why is it not possible to
> track changes by checking the SQL output the field will generate
> instead? This is guaranteed to be a string, and should be readily
> available for any field. I am just trying to get up to speed here...
>

This isn't particularly robust. The SQL string generated by a
particular backend isn't considered part of any API, and might change
formatting or semantics on minor updates. Some SQL is quite
complicated and dubiously related to the particular field, such as
extra INDEX or UNIQUE constraint statements. Certain backends elide
some arguments, performing constraint checking in the application (the
sqlite backend for example just drops many constraints). In general,
you want the migrations to be DB-agnostic, and checking SQL output
loses this feature.

>>  - Requiring all fields to be accessible by only their app label and
>> class name/other unique name.
>>
>> This means either having to register custom fields (like admin classes,
>> for example), or requiring fields to live in a fields.py or fields
>> package (like models and models.py). This is to provide for a
>> less-fragile way of referring to them than their full module path (which
>> might change based on project name or package location).
>
> As an idea, why not mimic the models.Model.__new__. You could have
> Field.__new__ which does the registration. A field could have
> app_label and "field name" as Meta (or just base level arguments). If
> these are not supplied, they will be generated by the __new__ from the
> field's class.__name__ and module. Once backwards compatibility period
> is over the meta variables are required.
>
> Any field which is never imported will never get registered, but I
> don't see that as a problem - if the field is not in use in the
> project, why should it need to be registered?
>

Adding additional invariants to Fields like "the (trailing module
path, ClassName) tuple must be unique over all fields" is arguably
backwards incompatible. Registering has several benefits. For example,
it doesn't impose any constraints until you decide that you want to
use migrations, at which point a nice error can be thrown: "Model Foo
has an unknown field: `field_name` of type: `project.app.CustomField`.
Please register this field with
`django.db.migrations.register_field()` before creating migrations on
the Foo model." Also, you can support third-party fields by
registering them in your own modules if you need to instead of hacking
on their code if they haven't updated it.

Best,
Alex Ogier

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to