Opened 18 years ago
Closed 18 years ago
#2289 closed defect (wontfix)
sqlall etc. don't work on models within a package
Reported by: | 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 , 18 years ago
comment:2 by , 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 , 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 , 18 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
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 , 18 years ago
Resolution: | duplicate |
---|---|
Status: | closed → reopened |
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 import
ed 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 , 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 , 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 , 18 years ago
Resolution: | → wontfix |
---|---|
Status: | reopened → closed |
Using app_label on each model is a workable solution. There's not enough of a problem here to be worth chasing up.
This may be a silly question, but does your
__init__.py
specify which files are part of the module?