1

I have:

script1.py in database/table_inserts/  #trying to import below file into
dbcrud.py in database/                 #trying to import by above file

in script1.py I have:

from ..dbcrud import set_db_setting

but this throws error:

   from ..dbcrud import set_db_setting
SystemError: Parent module '' not loaded, cannot perform relative import

What am i doing wrong?

Jshee
  • 2,440
  • 2
  • 40
  • 60
  • 1
    Do you have an `__init__.py` in the database directory? If so, I think you can do `from database import dbcrud`. – 2ps Feb 11 '17 at 03:16
  • No, i do not have one, what should it contain? – Jshee Feb 11 '17 at 03:17
  • I made a blank __init__.py in database/ , but that doesnt change anything – Jshee Feb 11 '17 at 03:21
  • @Jshee you need another one in the sub folder too, otherwise it won't be recognized as a package – Mad Physicist Feb 11 '17 at 03:53
  • 1
    Possible duplicate of [Relative imports in Python 3](http://stackoverflow.com/questions/16981921/relative-imports-in-python-3) – McGrady Feb 11 '17 at 03:56
  • @MadPhysicist - sadly, after putting it in `database/` and `database/table_inserts` it still wont let me import `dbcrud.py` into `script1.py` via `from dbcrud import function` – Jshee Feb 11 '17 at 04:07
  • `from ..dbcrud import function` is still the right way. The double dot is crucial – Mad Physicist Feb 11 '17 at 04:13

1 Answers1

7

Edit:

Thanks to @Mad Physicist comments.

The most easy and trivial way to solve your question is to add an empty __init__.py file in database/ folder and another empty __init__.py file to database/table_inserts/ folder in order to be recognized as a package.

See this example of hierarchy:

database/
├── dbcrud.py
├── __init__.py
└── table_inserts
    ├── __init__.py
    └── script1.py

1 directory, 4 files

Then all you have to do in script1.py is to import your module from dbcrud.py like this example:

# Note here the double dots '..'
from ..dbcrud import you_module

Otherwise, if you want another solution, you can edit your $PYTHONPATH variable like this way:

dbcrud.py:

class DBCrud:
    def __init__(self):
        print("I'm DBCrud'")

script1.py

# Add the parent directory to your module
# by using this kind of hack
import os, sys
sys.path.insert(1, os.path.join(sys.path[0], '..'))
# Then import your module
from dbcrud import DBCrud

class Script1:
    def __init__(self):
        print("I'm Script1'")
        DBCrud.__init__(self)

# test
if __name__ == '__main__':
    app = Script1()

Now, from database/ folder or database/table_insers/ folder you can run the test example:

~$ pwd
/user/path/database/table_inserts
~$ python3 script1.py

Output:

I'm Script1'
I'm DBCrud'

And:

~$ pwd
/user/path/database
~$ python3 table_inserts/script1.py

Output:

I'm Script1'
I'm DBCrud'
Chiheb Nexus
  • 8,494
  • 4
  • 28
  • 42
  • 3
    Thanks for this lengthy post. I just feel like it should be easier? – Jshee Feb 11 '17 at 03:50
  • Yes, it's easy, you need just to add `sys.path.insert(1, os.path.join(sys.path[0], '..'))` to your `script1.py` then import your module there. If you can't do it right, follow my example and everything will be right. – Chiheb Nexus Feb 11 '17 at 03:52
  • @Jshee. Ignore 99% of this answer. Just add a second init in database/table_inserts – Mad Physicist Feb 11 '17 at 03:56
  • @MadPhysicist does my answer is false ? Could you explain more please ? – Chiheb Nexus Feb 11 '17 at 03:58
  • 1
    You are doing way too much for a simple problem. If your packages are set up properly, you should never need to edit sys.path. – Mad Physicist Feb 11 '17 at 04:01
  • 1
    specifically, op's import method (from ..dbcrud import...) would work if the sub-package had an init file – Mad Physicist Feb 11 '17 at 04:03
  • 1
    No problem. Ill upvote when you edit your answer. The folder structure is the most important part, so could you make a note about the init file being necessary for a folder to be recognized as a package? – Mad Physicist Feb 11 '17 at 04:16
  • Thanks again for your comment. I've edite my answer. – Chiheb Nexus Feb 11 '17 at 04:27