Getting missing column error whenever a model is saved - python

I'm having trouble creating a model in django. I wrote a model like this:
from django.db import models
class FooModel(models.Model):
name = models.CharField(max_length = 255)
I run
manage.py syncdb
But when I'm in the shell, I can't save an instance. Every time I call it, it tells me it's missing a column
manage.py shell
>>from app.models import FooModel
>>foo = FooModel()
>>foo.name = 'foo'
>>foo.save()
DatabaseError: column "name" of relation "ecommerce_foomodel" does not exist
LINE 1: INSERT INTO "ecommerce_foomodel" ("name") VALUES (E'123123as...
We're using postgres.

The database table was created before you added the corresponding fields.
So, you can recreate all of the tables of that app (in case you don't have any useful data) using:
python manage.py reset ecommerce
Or, you should migrate the database to the latest version using South.

Related

FieldError: Unsupported lookup for CharField or join on the field not permitted on Django

Why do I get this error: FieldError: Unsupported lookup 'unaccent' for CharField or join on the field not permitted?
Info
Language: Python
Platform: Django
Database: PostgreSQL
Code
View:
def search(request):
query = request.GET.get("query")
searched = Book.objects.filter(title__unaccent__icontains=query) # Error here
return render(request, "main/search.html", {
"query": query,
"searched": searched,
})
Expected output
Unaccent the query and search for the unaccented version in the database.
Description
I get the error FieldError: Unsupported lookup 'unaccent' for CharField or join on the field not permitted when I try to query the database using __unaccent while using the advanced search features mentioned in the django docs.
If unaccent or any other PostgreSQL specific lookup, first
Add django.contrib.postgres to your settings.py INSTALLED_APPS.
Activate the lookup's extension on PostgreSQL. For unaccent, click here (under "Usage"), or you could
Perform the extension's migration operation. For unaccent, the extension is called UnaccentExtension. You can do this migration operation by
$ ./manage.py makemigrations --empty your_app_name
Then head over to the migration file created in the migrations folder of your app. If you're not sure which one is the file that was just created, the newest file is usually the one you created. To be extra careful, look into the terminal output that was displayed after you ran the above command. It is going to include the name of the file under the heading Migrations for your_app_name.
Then, in that file, delete the content and paste this:
from django.contrib.postgres.operations import UnaccentExtension
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('<your_app_name>', '<previous_migration_file>'),
]
operations = [
UnaccentExtension()
]
In the above code, replace <your_app_name> with the name of your app, and previous_migration_file with the name of the migration file before this one, not including the .py file extension. To find the previous migration file, look at the number of the migration file you're in (for example, in 0008_auto_20220104_1352, 0008 is the number of the file) and subtract 1 (for example, the previous file of 0008_auto_20220104_1352 is going to start with 0007).
After making the changes, python3 manage.py migrate to migrate your changes. You can now access the unaccent extension.

Automatically create django model instances at startup with empty database

My django project requires some model instances to be created at startup if they do not exist.
I currently create the required model instances I need in an app config.
class MyAppConfig(AppConfig):
name = 'my_app'
def ready(self):
create_required_objects()
def create_required_objects():
from my_app.models import MyObject
for name in MyObject.reserved_names:
if not MyObject.objects.filter(name=name).exists():
MyObject.objects.create(name=name, not_editable=True)
This works perfectly when the sqlite database is initialized, however if I clear the database and then try to run the sever, I get the following error:
django.db.utils.OperationalError: no such table: my_app_object
I would like to be able to clear the database (preferably by just removing db.sqlite3) and run the server.
Use post_migrate signal to create a new instance when migrating to the new database:
Like:
from django.db.models.signals import post_migrate
from my_app.models import MyObject
def create_required_objects(sender, **kwargs):
for name in MyObject.reserved_names:
if not MyObject.objects.filter(name=name).exists():
MyObject.objects.create(name=name, not_editable=True)
class MyAppConfig(AppConfig):
name = 'my_app'
def ready(self):
post_migrate.connect(create_required_objects ,sender=self)
This code automatically generates the user after migrating to the database.
You can use model_bakery to populate some temp data. You may need to do makemigrations and migrate to set up all tables in your database, you can follow this workflow.
python manage.py makemigrations
python manage.py migrate
In terms of populating data, you can try the following code:
from model_bakery import baker
from my_app.models import MyObject
baker.make(MyObject)
Add baker.make(MyObject) in your create_required_objects function after installation of model_bakery:
pip install model_bakery

Django : Dynamically create a database

I Would like to implement a web page in Django which allow a user to dynamically create a Data Base.
The Django model stored will always be the same. (a generic user)
Scenario :
The user fills up a form with fields like user.firstname, user.lastname ..
Then after the submit, django creates a brand new DB on the DBMS.
The model is then stored in this new DB.
Django save/store this DB setting for further use.
I find out Here that it's possible to set up multiple DB's in Django but that implies that they already have been created (Which is obviously not my case).
To create my DB I can think of executing an custom SQL query directly on the DBMS like that
from django.db import connection
def createNewDB(self,id):
with connection.cursort() as cursor:
queryStr = "\"CREATE DATABASE " + id + "\""
cursor.execute(queryStr)
But then I have no clues about :
How to save the new DB settings in Django DB (see below).
How to migrate and save the model user in the DB
Migrate :
from django.core.management import call_command
call_command("migrate", interactive=False)
Save model : user.save(using='db_id')
I find this post talking about how to add a connection dynamically with :
from django.db import connections
connections.databases['new-alias'] = { ... }
conn = connections['new-alias']
But again in, this case the sqlite DB exist before, so I'm not sure if it is what I need.
So is it possible to create a DB link to a model and then add it to django's database setting ?
Or should I review all my data structure ? (like one DB but multiple user model table)
I am using django 2.0.5 and postgreSQL 9.6 but I can change if the solution is not compatible (sqlite for example).

How to migrate existing table using Django and Python

I need one help. I have one existing mysql table in my localhost database and I need it to migrate using Django and Python. Here is my code:
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'djangotest',
'USER': 'root',
'PASSWORD': '',
'HOST': '',
'PORT': '',
}
}
I am giving my table structure below.
Person:
id name phone age
models.py:
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class Person(models.Model):
name = models.CharField(max_length=200)
phone = models.CharField(max_length=15)
age = models.IntegerField()
Actually I am new to Django and Python and here I need to know command which can migrate the existing table.
to create migrations you need to use this command -
python manage.py makemigrations
the above command will create a file inside the migrations folder in your app directory and
to create/update table using the migration file in the database
python manage.py migrate
The above command will create/update a table in your DB.
Django Migration Docmentation
Let me know, if this is what you want!
In reference to akhilsp, I did not have to worry about table names using the _ format. Using the inspectdb command returned a Meta data for whatever the current table name is that I used in my model.
class Meta:
managed = False
db_table = 'malware'
Add --fake option to migrate command:
--fake
Tells Django to mark the migrations as having been applied or unapplied, but without actually running the SQL to change your
database schema.
This is intended for advanced users to manipulate the current
migration state directly if they’re manually applying changes; be
warned that using --fake runs the risk of putting the migration state
table into a state where manual recovery will be needed to make
migrations run correctly.
If you just start django project and didn't have initial migration: comment your Person model, make initial migration, apply it, uncomment Person, make migration for Person and at last migrate Person with --fake option.
You can use inspectdb command from the shell.
python manage.py inspectdb
This will print models corresponding to the current database structure. You copy the required model, make changes like adding validations, and then add other models.
python manage.py makemigrations will create migrations, and
python manage.py migrate will apply those migrations.
N.B: Your table name should be in the format "appname_modelname" where appname is name for django app name (not project name).

How to remove all of the data in a table using Django

I have two questions:
How do I delete a table in Django?
How do I remove all the data in the table?
This is my code, which is not successful:
Reporter.objects.delete()
Inside a manager:
def delete_everything(self):
Reporter.objects.all().delete()
def drop_table(self):
cursor = connection.cursor()
table_name = self.model._meta.db_table
sql = "DROP TABLE %s;" % (table_name, )
cursor.execute(sql)
As per the latest documentation, the correct method to call would be:
Reporter.objects.all().delete()
If you want to remove all the data from all your tables, you might want to try the command python manage.py flush. This will delete all of the data in your tables, but the tables themselves will still exist.
See more here: https://docs.djangoproject.com/en/1.8/ref/django-admin/
Using shell,
1) For Deleting the table:
python manage.py dbshell
>> DROP TABLE {app_name}_{model_name}
2) For removing all data from table:
python manage.py shell
>> from {app_name}.models import {model_name}
>> {model_name}.objects.all().delete()
Django 1.11 delete all objects from a database table -
Entry.objects.all().delete() ## Entry being Model Name.
Refer the Official Django documentation here as quoted below -
https://docs.djangoproject.com/en/1.11/topics/db/queries/#deleting-objects
Note that delete() is the only QuerySet method that is not exposed on a Manager itself. This is a safety mechanism to prevent you from accidentally requesting Entry.objects.delete(), and deleting all the entries. If you do want to delete all the objects, then you have to explicitly request a complete query set:
I myself tried the code snippet seen below within my somefilename.py
# for deleting model objects
from django.db import connection
def del_model_4(self):
with connection.schema_editor() as schema_editor:
schema_editor.delete_model(model_4)
and within my views.py i have a view that simply renders a html page ...
def data_del_4(request):
obj = calc_2() ##
obj.del_model_4()
return render(request, 'dc_dash/data_del_4.html') ##
it ended deleting all entries from - model == model_4 , but now i get to see a Error screen within Admin console when i try to asceratin that all objects of model_4 have been deleted ...
ProgrammingError at /admin/dc_dash/model_4/
relation "dc_dash_model_4" does not exist
LINE 1: SELECT COUNT(*) AS "__count" FROM "dc_dash_model_4"
Do consider that - if we do not go to the ADMIN Console and try and see objects of the model - which have been already deleted - the Django app works just as intended.
django admin screencapture
Use this syntax to delete the rows also to redirect to the homepage (To avoid page load errors) :
def delete_all(self):
Reporter.objects.all().delete()
return HttpResponseRedirect('/')
You can use the Django-Truncate library to delete all data of a table without destroying the table structure.
Example:
First, install django-turncate using your terminal/command line:
pip install django-truncate
Add "django_truncate" to your INSTALLED_APPS in the settings.py file:
INSTALLED_APPS = [
...
'django_truncate',
]
Use this command in your terminal to delete all data of the table from the app.
python manage.py truncate --apps app_name --models table_name
There are a couple of ways:
To delete it directly:
SomeModel.objects.filter(id=id).delete()
To delete it from an instance:
instance1 = SomeModel.objects.get(id=id)
instance1.delete()
// don't use same name
Actually, I un-register the model (the table data that I want to delete) from the admin.py. Then I migrate.
python manage.py makemigrations
python manage.py migrate
python runserver
Then I register the model in the admin.py and do migration again. :) Now, the table is empty. This might not be a professional answer, but it helped me.

Categories

Resources