Opened 18 years ago

Closed 18 years ago

#2289 closed defect (wontfix)

sqlall etc. don't work on models within a package

Reported by: adurdin@… Owned by: Adrian Holovaty
Component: Database layer (models, ORM) Version:
Severity: normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I was trying to split my models.py out into separate modules to prevent it becoming too monolithic, so I created a models package. I moved some of the classes into models/init.py, and the other I split off into several other modules in the models package.

Now when trying to update the database for the new models I've created, I found that manage.py sql <appname> only outputs sql for the classes in models/init.py, and not for any of the other modules.

Change History (8)

comment:1 by James Bennett, 18 years ago

This may be a silly question, but does your __init__.py specify which files are part of the module?

comment:2 by adurdin@…, 18 years ago

Should it be necessary to have all the classes in the package namespace? I don't believe so. Half the reason for trying to create separate modules was so I'd have separate namespaces to group related models.

But to answer your question: before posting the ticket, I'd tried both:

# other models get missed
models/init.py # core models
models/other.py # other models

and

# all models get missed
models/init.py # contains 'from app.models.core import A, B' and 'from app.models.other import C, D'
models/core.py # core models
models/other.py # other models

With the latter, manage.py sqlall didn't output sql for any models.

comment:3 by adurdin@…, 18 years ago

Sorry, tried to use the wrong markup for code blocks (too-many-wiki-syntaxes syndrome). Those should have been:

# other models get missed
models/__init__.py  # core models
models/other.py     # other models

and

# all models get missed
models/__init__.py  # contains 'from app.models.core import A, B' and 'from app.models.other import C, D'
models/core.py      # other models
models/other.py     # other models

comment:4 by Malcolm Tredinnick, 18 years ago

Resolution: duplicate
Status: newclosed

This is kind of a wart, but it is possible to work around: put an app_label attribute on the inner Meta class in each of your models. The value of this attribute should be the dotted Python path to the application directory. So if your directory structure looks like

project/
   application/
      models/
         __init__.py
         mymodels1.py
         mymodels2.py
         ...

Then app_label on each model would be 'project.application'.

Fixing this in a better way is the topic of #1821.

comment:5 by adurdin@…, 18 years ago

Resolution: duplicate
Status: closedreopened

That workaround is no good for several reasons, the most obvious being that it doesn't work at all; manage.py still fails to see the other models--although the models are imported into models/__init__.py, and each models has class Meta: app_label='myproject.myapp' (the names I'm using in an isolated test project).

But more importantly, the workaround isn't suitable because:

  • The application I'm developing is intended to be used in several different projects, so it must be independent of the project name
  • Even if it did work, it still requires all the models to be in a flat namespace, which is not desirable.

I can't see the connection between this problem and #1821 -- can you enlighten me?

comment:6 by Malcolm Tredinnick, 18 years ago

The connection with #1821 is that it provides a way to specify once what the application label is. That is the hard bit here: we need to know the app name in a number of places.

comment:7 by adurdin@…, 18 years ago

After poring over db/models/loading.py and db/models/base.py, I finally found that app_label should have been myapp, not myproject.myapp; then it works as advertised.

It's not a perfect solution, but it's close enough for me right now. Cheers!

comment:8 by adurdin@…, 18 years ago

Resolution: wontfix
Status: reopenedclosed

Using app_label on each model is a workable solution. There's not enough of a problem here to be worth chasing up.

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