Opened 7 years ago
Closed 7 years ago
#28746 closed Bug (invalid)
Model missing custom Meta option in migrations
Reported by: | JP Navarro | Owned by: | nobody |
---|---|---|---|
Component: | Migrations | Version: | 1.10 |
Severity: | Normal | Keywords: | abstract Meta inheritance |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Given:
class AbstractGlue2Model(models.Model): ID = models.CharField(primary_key=True, max_length=200) <stuff> class Meta: abstract = True db_name = 'glue2' ... class Contact(AbstractGlue2Model): Detail = models.CharField(max_length=128) Type = models.CharField(max_length=16)
A migrate that should create the new Contacts DB objects sees inherited fields (such as ID), but is missing Meta db_name value:
(Pdb) pp hints['model'] <class 'Contact'> (Pdb) pp hints['model']._meta.db_name *** AttributeError: AttributeError("'Options' object has no attribute 'db_name'",) (Pdb) pp hints['model']._meta.abstract False (Pdb) pp hints['model'].ID <django.db.models.query_utils.DeferredAttribute object at 0x10f97d6d0>
Change History (6)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
This issue is related to Ticket #5793 https://code.djangoproject.com/ticket/5793.
I submitted this as a bug because the behavior changed. Prior to 1.10 custom Meta attributes were passed on, as of 1.10.7 they are filtered out.
follow-up: 4 comment:3 by , 7 years ago
With your sample code, I get an exception even on Django 1.9 and older: TypeError: 'class Meta' got invalid attribute(s): db_name
. If you see a behavior change, can you bisect to find the commit where it changed? Even if there's a behavior change, I don't think there's much obligation to restore the old behavior as it's undocumented and untested.
comment:4 by , 7 years ago
Replying to Tim Graham:
With your sample code, I get an exception even on Django 1.9 and older:
TypeError: 'class Meta' got invalid attribute(s): db_name
. If you see a behavior change, can you bisect to find the commit where it changed? Even if there's a behavior change, I don't think there's much obligation to restore the old behavior as it's undocumented and untested.
Ah, I missed the following code in a custom router where the db_name model Meta attribute gets used:
import django.db.models.options as options
options.DEFAULT_NAMES = options.DEFAULT_NAMES + ('db_name',)
So, i tracked the problem down to makemigrations which isn't propagating the 'db_name' attribute to the migration. Does this help narrow down what change caused this, or do you still need the commit where it changed?
Incidentally, if there is a better way to identify a database where a model is suppose to exist I'm open to suggestions. The goal is to identify it with the Model and not somewhere unrelated like a custom router.
comment:5 by , 7 years ago
Yes, it would be helpful if you could bisect. Also, the steps to reproduce the issue aren't very explicit.
comment:6 by , 7 years ago
Component: | Database layer (models, ORM) → Migrations |
---|---|
Resolution: | → invalid |
Status: | new → closed |
Summary: | New model missing abstract model inherited Meta/Options → Model missing custom Meta option in migrations |
I bisected the behavior change to 50931dfa5310d5ae1c6e2852d05bf1e86700827f. It's seemingly unrelated but I guess the issue may be related to import changes in that patch and timing in which the options.DEFAULT_NAMES
monkeypatch is running. Feel free to reopen if you do further investigation and find that Django is at fault.
Just noticed the relevant migration is missing the db_name: