Using DJANGO_SETTINGS_MODULE in a script in subfolder - python

In order to populate the database of my Django application, I created a small script that reads a CSV (a list of filenames) and creates objects accordingly:
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
import django
django.setup()
import csv
import sys
from myapp.models import Campaign, Annotation
campaign_name = "a_great_name"
path_to_csv = "filenames.csv"
with open(path_to_csv) as f:
reader = csv.reader(f)
filenames = [i[0] for i in reader]
new_campaign = Campaign.objects.create(name=campaign_name)
for i in filenames:
new_annotation = Annotation(
campaign=new_campaign,
asset_loc = i)
new_annotation.save()
I saved this script at the root of my project: myrepo/populator.py
and it worked fine.
… until I decided to move it into a subfolder of my project (it’s a bit like an admin tool that should rarely be used): myrepo/useful_tools/import_filenames/populator.py
Now, when I try to run it, I get this error: ModuleNotFoundError: No module named 'myproject'
Sorry for the rookie question, but I’m having a hard time understanding why this happens exactly and as a consequence, how to fix it. Can anybody help me?

Yes, the problem arose when you changed the script location because then the root directory was not in the sys.path list anymore. You just need to append the root directory to the aforementioned list in order to be able to load the settings.py file of your project.
If you have the script now in myrepo/useful_tools/import_filenames/populator.py, then you will need to go back three folders down in your folders tree to be back in your root directory. For this purpose, we can do a couple of tricks using the os module.
import os
import sys
sys.path.append(os.path.abspath(os.path.join(__file__, *[os.pardir] * 3)))
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
import django
django.setup()
print('loaded!')
# ... all your script's logic

Related

Can't find the file from views.py

I am stuck with a really weird problem.
I have a file called: "test.txt".
It is in the same directory with views.py. But I can't read it... FileNotFoundError.
But if I create read_file.py in the same directory with views.py and test.txt, it works absolutely fine.
What is wrong with views? Is this some sort of restriction by Django?
This code works on read_file, doesn't work on views.py:
fkey = open("test.txt", "rb")
key = fkey.read()
I think the problem may be relative vs absolute file handling. Using the following Python snippet, you can work out where the interpreter's current working directory is:
import os
print(os.getcwd())
You should notice it's not in the same directory as the views.py, as views.py is likely being invoked/called from another module. You may choose to change all your open calls to include the whole path to these files, or use an implementation like this:
import os
# This function can be used as a replacement for `open`
# which will allow you to access files from the file.
def open_relative(path, flag="r"):
# This builds the relative path by joining the current directory
# plus the current filename being executed.
relative_path = os.path.join(os.path.dirname(__file__), path)
return open(relative_path, flag) # return file handler
Then, this should work:
fkey = open_relative("test.txt", "rb")
key = fkey.read()
Hope this helps!

Can't import module from different directory python

So below I have is my file structure:
/
api.py
app.py
code/
data_api/
weather_data/
get_data_dir/
get_data.py
master_call_dir/
master_call.py
My current problem is that I'm importing master_call.py from inside app.py I do this with the following code:
-- app.py
import sys
sys.path.append('./code/data_api/weather_data/master_call_dir')
from master_call import master_call_interface as master_call
Importing master_call itself works perfectly fine, the issue is that inside off master_call I import get_data.py. I do this with the following code:
-- master_call.py
import sys
sys.path.append("../get_data_dir")
from get_data import get_data_module
When printing out sys.path I can see ../get_data_dir inside of it but Python still isn't able to find the get_data.py file in /get_data_dir.
Does anyone know how to fix this?
(there is an __init__.py file in every directory, I removed it here for readability)
So I figured it out. The problem is while the directory of the master_call.py file is /code/data_api/weather_data/master_call the current working directory (CWD) is / since that is where app.py is located.
To fix it we simply fetch absolute file path in each python script with
current_path = os.path.dirname(os.path.realpath(__file__)).replace('\\', '/')
and pre-pend it to any file path we're appending with sys.path.append
So it'd look like this in practice:
import sys
import os
current_path = os.path.dirname(os.path.realpath(__file__)).replace('\\', '/')
sys.path.append(f'{current_path}./code/data_api/weather_data/master_call_dir')
from master_call import master_call_interface as master_call

how to call and execute file in another folders file?

I need to call 'test.txt' file in 'req.py' to execute some data.
File structure:
application - 1.Foldername -- req1.py
2.test.txt
will the same structured will be followed in the azure function app to call text.txt?
#req1.py
file1 = open(r'application/test.txt',"r")
print(file1.readlines())
file1.close()
Yes we can call the files from other folders and can read them, as below:
ReproScreenshot
We can just simply import .py files in the same folder by adding import pythonfile
Below are few ways like how we can include python files.
Including modules:
import sys
# Insert the path of modules folder
sys.path.insert(0, "C:\\Users\\anila\\Desktop\\Task\\modules")
# Import the module0 directly since
# the current path is of modules.
import firstModule
# Prints "Module0 imported successfully"
firstModule.run()
Import method:
import sys
sys.path.insert(0, 'path/to/your/py_file')
import py_file

ImportError: No module named modules.TestModule

I have been stuck in this issue for a long time, my project structure goes like this,
import web
import sys
sys.path.append("...")
import modules.TestModule as TM
urls = (
'/testmethod(.*)', 'TestMethod'
)
app = web.application(urls, globals())
class TestMethod(web.storage):
def GET(self, r):
return TM.get_func(web.input().string)
if __name__ == "__main__":
app.run()
When I execute the TestService.py it says "ImportError: No module named modules.TestModule Python"
This is a sample made to test the module.
What is the entry point for your program? Usually the entry point for a program will be at the root of the project. Since it is at the root, all the modules within the root will be importable.
But in your case entry point itself is a level inside the root level.
The best way should be have a loader file (main.py) at root level and rest can be in packages. The other non-recommended way is to append root directory path in sys.path before importing any package.
Add below code before you import your package.
import os, sys
currDir = os.path.dirname(os.path.realpath(__file__))
rootDir = os.path.abspath(os.path.join(currDir, '..'))
if rootDir not in sys.path: # add parent dir to paths
sys.path.append(rootDir)
I have modified yut testscript.py code as below. Please try it out.
import web
import sys
import os, sys
currDir = os.path.dirname(os.path.realpath(__file__))
rootDir = os.path.abspath(os.path.join(currDir, '..'))
if rootDir not in sys.path: # add parent dir to paths
sys.path.append(rootDir)
import modules.TestModule as TM
urls = (
'/testmethod(.*)', 'TestMethod'
)
app = web.application(urls, globals())
class TestMethod(web.storage):
def GET(self, r):
return TM.get_func(web.input().string)
if __name__ == "__main__":
app.run()
If the directory 'DiginQ' is on your python sys.path, I believe your import statement should work fine.
There are many ways to get the directory 'DiginQ' on your python path.
Maybe the easiest (but not the best) is to add a statement like this before you import modules.Testmodule:
import sys
sys.path.extend([r'C:\Python27\DiginQ'])
Based on your post it looks like the path is C:\Python27\DiginQ but if that's not correct just use the right path.
If you google how to set python path you will find many hits. Most important thing is your path has to include the directory above the directory with the package you are attempting to import. In your case, that means DiginQ.

Python import file with dependencies in the same folder

I have a file ref.py that depends on a text file ex.txt, that is in the same directory \home\ref_dir . So it works normally when I run the file ref.py, but if I try to import ref.py to another file work.py in a different directory \home\work_dir , I do the following
import sys
sys.path.append('\home\ref_dir')
import ref
But then I get an error, that the program cannot find ex.txt
How can I solve this issue without using absolute paths. Any ideas?
Use the os module to get access to the current absolute path of the module that you're in, and then get the dirname from that
You would want to open ex.txt in your file like this.
import os
with open('%s/ex.txt' % os.path.dirname(os.path.abspath(__file__)) as ex:
print ex.read()

Categories