I have a django project that was created on an Oracle database and I want to switch to ANOTHER Oracle database. I have followed this tutorial https://pythonfusion.com/switch-database-django/, but there is a problem that not all models are created initially in Django, some are created using inspectdb on existing tables in other databases . Therefore, when using the migrate --database=new command, I get errors about those tables that already existed before Django was created. Is there a way to migrate only the models and tables necessary for Django to work? (users, auth...)
I think you have to take a look at the managed attribute of each model meta class.
If managed is true then django will change the model in the database.
Unmanaged model :
class MyModel(models.Model):
...
class Meta:
managed = False # This means django will ignore MyModel when migrating
Managed model :
class MyManagedModel(models.Model):
...
class Meta:
managed = True # This means django will migrate MyManagedModel
More documentation here : https://docs.djangoproject.com/en/4.1/ref/models/options/
Yes you can definitely customize your migration behavior, the command python manage.py makemigrations creates a couple of files that are used to migrate your models into your DB, any who you can still access these files and choose exactly what to include, exclude and even edit them.
Check the following link:
https://dev.to/koladev/writing-custom-migrations-in-django-3eli
If I've understood your question correctly, then you're looking to use Django's built-in migrations. To find out which migrations have been run against your new database, run the command manage.py showmigrations --database=new which will show you a list of all migrations that exist within the context of your application.
Once that is done, you can manually run the desired migrations (e.g. auth and contenttypes) by running the command manage.py migrate --database=new app_label migration_name.
showmigrations command: https://docs.djangoproject.com/en/4.1/ref/django-admin/#django-admin-showmigrations
migrate command: https://docs.djangoproject.com/en/4.1/ref/django-admin/#django-admin-migrate
Related
I have an old table in the database. And I want to create a model in Django application.
After creating a model and I used migrate command then it created a new table with its own name.
Django provides a utility to auto-generate models from an existing database via inspectdb command.
You can create models by introspecting an existing database by executing following command
python manage.py inspectdb
The above command will output all the models Django can create from the existing database to stdout. You can save this as a file by using standard Unix output redirection
python manage.py inspectdb > models.py # or pass the app_name.models.py if you want to generate them inside models.py file of specific app
The output file will be saved to your current directory. Move that file to the correct app and you have a good starting point for further customization.
you can refer https://docs.djangoproject.com/en/4.1/ref/django-admin/#django-admin-inspectdb for more information.
You can specify the table name by setting table on the model's Meta class. Set managed = False to prevent Django from creating the table.
class ExistingModel(models.Model):
...
class Meta:
table = 'existing_table'
managed = False
After making these changes, I would revert the previous migration, remove the migration file, then run makemigrations again.
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/
In my django application (django 1.8) I'm using two databases, one 'default' which is MySQL, and another one which is a schemaless, read-only database.
I've two models which are accessing this database, and I'd like to exclude these two models permanently from data and schema migrations:
makemigrations should never detect any changes, and create migrations for them
migrate should never complain about missing migrations for that app
So far, I've tried different things, all without any success:
used the managed=False Meta option on both Models
added a allow_migrate method to my router which returns False for both models
Does anyone have an example of how this scenario can be achieved?
Thanks for your help!
So far, I've tried different things, all without any success:
used the managed=False Meta option on both Models
That option (the managed = False attribute on the model's meta options) seems to meet the requirements.
If not, you'll need to expand the question to say exactly what is special about your model that managed = False doesn't do the job.
I thought, I have a problem with makemigrations. It pretends to make migration on managed = False model, but no SQL code generated for this model
Here is my example, model Smdocumets unmanaged, and no SQL code was generated.
python manage.py makemigrations
Migrations for 'monitor':
monitor\migrations\0005_auto_20171102_1125.py
- Create model Smdocuments
- Add field sid to db
- Alter field name on db
python manage.py sqlmigrate monitor 0005
BEGIN;
--
-- Create model Smdocuments
--
--
-- Add field sid to db
--
ALTER TABLE "monitor_db" RENAME TO "monitor_db__old";
...
You have the correct solution:
used the managed=False Meta option on both Models
It may appear that it is not working but it is likely that you are incorrectly preempting the final result when you see - Create model xxx for models with managed = False when running makemigrations.
How have you been checking/confirming that migrations are being made?
makemigrations will still print to terminal - Create model xxx and create code in the migration file but those migrations will not actually result in any SQL code or appear in Running migrations: when you run migrate.
In my django project I use django-registration reusable app. I install this app and run syncdb. It's create for me table 'registration_registrationprofiles' in my database. Then I create a new app and write this code in my models.py:
class Comments(models.Model):
text = models.TextField()
pub_date = models.DateTimeField(auto_now=True)
user = models.ForeignKey('registration_registrationprofiles')
And run manage.py makemigrations and it throw me exception:
ERRORS:
comments.Comments.user: (fields.E300) Field defines a relation
with model 'registration_registrationprofiles', which is either
not installed, or is abstract.
How I can fix this problem?
Try this:
from registration.models import RegistrationProfile
and then:
user = models.ForeignKey(RegistrationProfile)
Migrations can have dependencies declared. Usually, makemigrations does a good job with that, but it looks like it missed it this time. I suggest you locate the migration file it created (in your_app/migrations) and check its dependencies. It should look like this:
class Migration(migrations.Migration):
dependencies = [("registration", "0042_some_migration")]
# operations...
The key here it the dependencies array should reference the registration app, and the latest migration (or at least the latest you depend on).
Then manage.py makemigrations will detect the dependency and run migrations in the correct order.
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?