Django Migration-SQL Server - python

I am just learning Django, I have created a model inside an app Book
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
read = models.CharField(max_length=50)
Now I want to generate it's correspondence SQL sentence with the help of
python manage.py sql books
But it's showing me error
CommandError: App 'Books' has migrations. Only the sqlmigrate and sqlflush commands can be used when an app has migrations.
I have used makemigrartion and migrate command it's showing no migration is remaining.
Can anyone have any idea regarding to this error?

Since there is still a bit of backwards compatibility with django 1.6 and below you can still use the sql commands from django-admin. However, you have to delete the migrations folder first.
To get the create statements you need to remove the migrations folder
rm -rf books/migrations
Then you can run the sql statement
./manage.py sql books
Should give you something like this:
BEGIN;
CREATE TABLE "books_book" (
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"title" varchar(100) NOT NULL,
"author" varchar(50) NOT NULL,
"read" varchar(50) NOT NULL
)
;
COMMIT;
However if what you are after is the select statements. Add back your migrations folder:
mkdir books/migrations/
Then do your create migrations and migrate commands.
From there open up the shell:
./manage.py shell
In the shell you can create a queryset and print the query:
from books.models import Book
print Book.objects.all().query
With that you should get an output like this:
SELECT "book_book"."id", "book_book"."title", "book_book"."author", "book_book"."read" FROM "book_book"
Those are a couple of ways to get sql back, depending on what you are trying to generate. The great thing about the queryset in the shell is you can make that as complex as possible and do a print of the .query and it gives it to you.

Hmm, interesting. Right now, there are two ways of turning models into SQL. The old syncdb method, which will ultimately be removed, and the new migrations method. The old sql* commands were based on the first method, and won't generally work the same way with the migrations approach. So I think this is a technical limitation (though perhaps it's philosophical as well).
Probably the best way to accomplish this is to first squash your migrations (in most cases this should produce a single migrations file) and then generate the SQL for that new migration with the sqlmigrate command.

Inside the app, there will be a directory for migrations where the django will store your model changes as migrations files.
To see the query you have to use the command python manage.py sqlmigrate {your_app_name;{eg :polls}} {migrations_file_name:{eg:0001_init.py}}
command:
python manage.py sqlmigrate polls 0001
Hope this will help

Related

How to use Django with an existing database in MySQL?

I have an application in Django 2.0 and as a database engine I use MySQL. I have a problem because the database was previously created and already has records, my idea is to use this same database for the application I am creating.
Use the command
python manage.py inspectdb > models.py
To create the models.py file which will be cleaned as indicated by the models.py file that was generated.
#This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey has `on_delete` set to the desired behavior.
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
After this I proceed to execute:
python manage.py migrate
python manage.py makemigrations
python manage.py migrate
But it generates the following error:
(1050, "Table 'XXXXXXX' already exists")
Obviously it tells me that the table already exists, but how do I not generate this error and continue administering the tables from Django.
You need to run --fake-initial or --fake. See more at Django migrations. Be careful because running inspectdb doesn't solve all your problems. You need to fix the things inside models.py manually and migrate again.
One of the things (and the main reason I do not use Django) is it likes to take control of everything. The fact that it controls the database means that if you don't start strictly in Django, you are doing it wrong.
However there is a work around:
https://docs.djangoproject.com/en/2.0/howto/legacy-databases/

Adding Columns to Existing Schema

I am just getting started with Django (1.8) and I am a bit confused about how to modify my models.
If I go in and add a new field to an existing model, I start getting "No Such Column" error. So far, I've just been wiping my DB and starting over, but that gets annoying, is there a process for this?
What happens when I go to production? How would I modify the schema at that point? All the resources I see online are for South, which I guess is built into this version of django, but still can't find any solid info.
Thanks
In django 1.7+ there is no need of south.Only
python manage.py makemigrations
python manage.py migrate
If you're changing over from an existing app you made in django 1.7-, then you need to do one pre-step (as I found out) listed in the documentation:
python manage.py makemigrations your_app_label
Also try this
class Mymodel(models.Model):
myfiled = models.CharField()
# ...
class Meta:
managed = True
You can write you own sql command to add the missing column giving you that error.
first run:
python manage.py makemigrations --empty yourappname
then you can go to your app and find the newly generated migration file
having a code similar to the code below.
I'm not sure the kind of column you want add but inside operations in the below code, you put your sql command. In my example I'm just adding a character varying field.
class Migration(migrations.Migration):
dependencies = [
('app_name', '0002_auto_20150619_2439'),
]
operations = [
migrations.RunSQL('ALTER TABLE mytable ADD COLUMN mycolumn character varying(50) NOT NULL')
]
I hope this helps.

MySql to Python Model Creation Tool

I want to migrate a site written in PHP/MySQL to a Python/Django. There will be some significant modifications to the application, but I am not expecting any significant changes to the backend persistence.
Essentially I would like to find a tool that will create the
django.db.models.Model
classes for me. For example consider:
create table blah (
a varchar(10) not null
, b varchar(10) not null
)
and I run the tool and it generates the following models.py file for me
class Blah(models.Model):
a = models.CharField(max_length=10)
b = models.CharField(max_length=10)
Something I can run command line OR wherever. Thanks, and I am new to python/django so I apologize if there is well known solution (although google isn't showing me one).
T
Django can handle it, see inspectdb management command:
Introspects the database tables in the database pointed-to by the NAME
setting and outputs a Django model module (a models.py file) to
standard output.
Also, consider using south for further schema and data migrations.

Django many to many relationship with built in "User" model

Scenario
I have a basic Django app in which users (django's authentication built in model) and reports have a many-to-many relationship.
The Problem
Django does not create a corresponding table to handle this relationship. My application is called reports. There is an error in the admin system upon trying to create a report and assign users to it. It tries to query the table reports_report_users and it fails as it does not exist.
models.py code
from django.db import models
from django.contrib.auth.models import User
class Report(models.Model):
name = models.CharField(max_length=30, blank=False)
users = models.ManyToManyField(User, related_name='reports')
def __unicode__(self):
return self.name
Attempted Solutions
Used this link as a reference: https://docs.djangoproject.com/en/1.4/topics/db/examples/many_to_many/
Ran manage.py syncdb about 300 times - ok, only once, but there were no errors and upon inspecting the SQLite db there were no additional tables created :(
It seems like you've added to the Report model after the first sync. Thus you're dealing with a migration, which django doesn't do natively.
First, Inspect the sql output, make sure that the create table instruction for your many to many relationship is there.
python manage.py sqlall
Assuming the problem is that this is a migration, which django doesn't handle natively, you've got three options:
1) Delete all db tables for this app, then run syncdb again.
2) Manually create the tables (fairly easy to copy paste the create sql from the sqlall command)
3) Start using a migration framework like South.
In the long run you'll appreciate the investment in learning south. In the short term, deleting the DB file is the fastest.-
Have you deleted your db file and run manage.py syncdb again?

How to update models.py when I create a new table in my database?

I was wondering how to automatically update my models.py in a specific app in django. I created a new table in my database through HeidySQL, when i syncdb, i see the table appears in the directory in the command line, but not in models.py . I also tried migrate and make migrations but still not working.
Any idea? Thanks!
The manage.py migrate and makemigrations commands work in the opposite direction that you are describing here. If you want to generate a starter template of your models based on the current layout of the database, you can try using the inspectdb command.
python manage.py inspectdb > temp_models.py
This will generate a starter model for every table in the database. You should review and update the generated models so they make sense with your app. Take special note of lines ending with the comment # This field type is a guess.
Once you are satisfied with the new models, copy them over to the app's models.py file.
Hope that helps!

Categories

Resources