I have a Django project that I've been working on for a while. I came to the point where I wanted to load a significant amount of data into my Postgres database. I set aside a new Django project with sqlite3 just to work out the code and run some tests to make sure everything was inserted properly.
Everything seemed fine until I got to the point where I actually wanted to test the insert script.
ImportError: attempted relative import with no known parent package
The error refers to this line in the script:
from .models import Statute
As of right now, this has no red squiggly line on it. models.py and this script are right beside each other in the same directory:
$ tree
└── parsecodetree
├── db.sqlite3
├── manage.py
├── parsecodetree
│ ├── asgi.py
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── ustitles
├── admin.py
├── apps.py
├── __init__.py
├── insert504.py
├── insert_script_results
├── migrations
├── models.py
├── t10p1b.html
├── tests.py
└── views.py
I found this trick in an old David Beazely video:
parsecodetree/ustitles/__init__.py:
from .models import *
print("This is ustitles.__init__")
“This is ustitles.__init__” does not print.
Commenting or uncommenting ‘from .models import *’ seems to make no difference.
However:
/home/malikarumi/Projects/uscode/parsecodetree/parsecodetree/__init__.py:
print("This is parsecodetree.__init__")
"This is parsecodetree.__init__" does print.
But apparently it also gets an error:
This is parsecodetree.__init__
Traceback (most recent call last):
<...snip…>
ModuleNotFoundError: No module named 'parsecodetree.parsecodetree'
I found this from RealPython.com more confusing than helpful. If __init__.py
is not required, why do I even have this issue to begin with?
https://realpython.com/lessons/package-initialization/
Note: Much of the Python documentation states that an
__init__.py
file must be present in the package directory when creating a package. This was once true. It used to be that the very presence of__init__.py
signified to Python that a package was being defined. The file could contain initialization code or even be empty, but it had to be present.Starting with Python 3.3, Implicit Namespace Packages were introduced. These allow for the creation of a package without any
__init__.py
file. Of course, it can still be present if package initialization is needed. But it is no longer required.
I saw a lot of stuff about setting the __package__
variable. But where do I put this assignment? I tried settings. That didn’t work.
I don’t understand the mapping from python “package” to django “Project”
BASE_DIR == “Project”, but are both also == “package” or “__package__
”?
In my setup, are both parsecodetree and ustitles “packages”? Whether I set them as == __package__
or not? Whether they have __init__.py
or not?
This SO post makes it seem like every directory needs an __init__.py
, just the opposite of the RealPython lesson. It doesn't seem DRY, either.
This gets red squiggly lines:
from ustitles.models import Statute
and a traceback to boot:
This is ustitles.__init__
Traceback (most recent call last):
<...snip…>
ModuleNotFoundError: No module named 'parsecodetree.parsecodetree'
But do you notice? Now “This is ustitles.__init__
” prints!
Along the same lines, how do you run “-m” with PyCharm “run”? Turns out this is still an open question: https://intellij-support.jetbrains.com/hc/en-us/community/posts/360003879119-how-to-run-python-m-command-in-pycharm-?page=1#community_comment_5925736517010