Django - pass commands to shell - python

I have an django project on Heroku and I need to update the DB daily. Manually i would open manage.py shell and write there this:
from app import views
views.function()
One way i found to do that automatic is through a heroku scheduler, however I would like to know if it is possible to tell the shell what commands should it run.
I was doing this:
python -c "from app import views;views.function"
but it gives me an error because that should be done on the shell instead of the command line, so is it possible to tell the shell what should it write?
Thanks :D

You can write a custom django command, something like my_command.py and call it from the command line:
python manage.py my_command
https://docs.djangoproject.com/en/1.11/howto/custom-management-commands/

Related

How to run a python script in the background django

I have a python script (ml.py)that generates some data. I want it to run it in the background daily at 1 AM. How to achieve that ?
ml.py
Takes input from the django models, runs some logic and save the results to the database
I tried installing django-background-tasks and created the following files
tasks.py
from background_task import background
#background(schedule=1)
def hello():
execute('./scripts/ml.py')
hello(repeat=Task.Daily)
In the shell, I executed the following command:
python manage.py process_tasks
Now I get an error saying that the name execute is not defined
My other questions are :
Do I have to write the command python manage.py process_tasks
everyday ?
Can I exit out of the command window and does the process
still run everyday ?

Problem with flask using Python 3.7.6 with vscode on mac

I have a weird problem with some code I want to run. The code itself should not be the problem since it is downloaded from a Udemy class and not modified:
# coding=utf-8
from flask import Flask, render_template, request
app = Flask(__name__)
#app.route("/")
def hello():
items = ["Apfel", "Birne", "Banane"]
return render_template("start.html", name="Max Mustermann", items=items)
#app.route("/test")
def test():
name = request.args.get("name")
return render_template("test.html", name=name)
I found online that, to start the emulated webserver(?) I have to rund the following temrinal commands before I can see the output:
(base) Christophs-MBP:13-23 chris$ export FLASK_APP=run.py run flask
(base) Christophs-MBP:13-23 chris$ export FLASK_APP=run.py run flask
(base) Christophs-MBP:13-23 chris$ export FLASK_APP=run.py
(base) Christophs-MBP:13-23 chris$ run flask
bash: run: command not found
No reaction to my terminal commands
Basically there is no reaction to the command to start the server(?).It should reply with "Running on 127.0.0.1:5000" as soon as I've run the command once.
If I go to my browser, there is no page when I address http://127.0.0.1:5000. What am I doing wrong? I am pretty new to Python and an absolute rookie regarding the terminal. Not sure if I broke something there, since trying to install pyenv to manage my Python installs better as recommended by a friend does not work either (I cannot update the SDK headers as described on RealPython
What are the export statements?
On Mac, export key=value creates a new (or updates an existing one) environment variable - the tutorial most likely simply asked you to provide one where key is FLASK_APP and value is a path to your app.
To verify it's been saved correctly, you can list the variables by just typing export in the terminal and finding out what's inside each of the environment variables on your system (if you want to only view FLASK_APP you can type export | grep FLASK_APP).
Why do you need FLASK_APP?
When you call flask run in your terminal, you will see the following message:
Error: Could not locate a Flask application. You did not provide the "FLASK_APP" environment variable, and a "wsgi.py" or "app.py"
module was not found in the current directory.
I presume your file is called run.py, therefore none of the conditions are met. You could rename run.py to app.py and simply type flask run in the terminal, but you can also type export FLASK_APP=<path-to-run.py>. It seems the tutorial author decided to do the latter. Keep in mind that if you rename your file to app.py you will need to run flask run within the directory that file lives in. You can change directory in the terminal using cd command.
Why do you get bash: run: command not found?
bash is a language running inside your terminal, and it only knows of a few commands - it is not aware of any run commands. It does however know about flask command once you have installed it on your machine. Within the command's output there is a part which includes a run command:
Commands:
routes Show the routes for the app.
run Run a development server.
shell Run a shell in the app context.
Therefore, what you want to do is type flask run instead of just run in your terminal.

How do I pipe a model query into the Django Shell via a Bash Script?

I'm writing a startup.sh script to be ran when a docker container is created.
#!/bin/bash
python manage.py runserver
python manage.py makemigrations accounts
python manage.py migrate
python manage.py check_permissions
python manage.py cities --import=country --force
*python manage.py shell | from cities.models import * Country.objects.all().exclude(name='United States").delete()*
python manage.py cities --import=cities
python manage.py cities --import=postal_code
I am guessing the line in question is incorrect, what would be the correct way to do this in a bash script?
Use a heredoc:
python manage.py shell <<'EOF'
from cities.models import *
Country.objects.all().exclude(name='United States').delete()
EOF
It's not such a good idea to include django code in a shell script file. It's better to either make a python file and put those code in it and do:
python manage.py shell < script.py
Or better, write a django management command. In this way you could track your code in the same project/repo and people got less confused when they see this.

How to automate django dumpdata?

I am populating my DB locally and I want to dump that data to the production server with a script for all my apps.
I am trying to write a script that will do this...
$ source path/to/venv && python manage.py dumpdata app1 > file1.json
$ source path/to/venv && python manage.py dumpdata app2 > file2.json
...etc
I use fabric for my deploy script and I thought it would be nice to incorporate it in there, but the 'local' method in fabric doesn't seem to be able to do such a thing. the run command does, but IDK why.
I think it might have something to do with this...
local is not currently capable of simultaneously printing and
capturing output, as run/sudo do. The capture kwarg allows you to
switch between printing and capturing as necessary, and defaults to
False. (http://docs.fabfile.org/en/latest/api/core/operations.html)
but I am not sure
I tried doing it with os.system n a separate python script as well but that didn't work either, both of them give me the same error which is...
sh: 1: source: not found
I have checked and double checked the path many times, I can't seem to figure it out. What do you think?
Your script executes under the classic sh shell, not under bash. "source" is a bash command; the classic import command is a period (like ". pathto/pyenv/bin/activate"). Or you could force bash with #!/bin/bash at the start of your script.
Since '$ source' was the thing that could not be executed. I made a shell script, placed it in a directory and just executed that
source pathto/pyenv/bin/activate && python manage.py dumpdata quiz > data_dump/foo.json
source pathto/pyenv/bin/activate && python manage.py dumpdata main > data_dump/bar.json
source pathto/pyenv/bin/activate && python manage.py dumpdata study > data_dump/waz.json
and then in the fabric file...
def foobar():
local('/pathto/foo.sh')

How to script django shell operations?

I'd like to create a script (.sh or python, not important) that can do the following:
heroku pg:reset DATABASE_URL
heroku run python manage.py migrate
heroku run python manage.py shell
> from myapp.scenarios import *; reset_demo_data(); exit()
Line 1 to 3 are UNIX commands, but Line 4 is python to be executed in the opened Django shell.
I tried stuff with | and > to "inject" the python code in the command but nothing worked.
I guess it's quite easy to do but I can't figure out how..
Thanks.
I guess the best option would be to write a custom management command.
Your script could then look like:
heroku pg:reset DATABASE_URL
heroku run python manage.py migrate
heroku run python manage.py shell
heroku run python manage.py reset_demo
when the management command is something like:
from django.core.management.base import BaseCommand
from myapp.scenarios import *
class Command(BaseCommand):
def handle(self, *args, **options):
reset_demo_data()
Or you can try this one line solution:
echo "from myapp.scenarios import *; reset_demo_data(); exit()" | python manage.py shell
You can add this line replacing Shell activation line.

Categories