Django Models UnManaged to Managed - python

Does changing Django Model from managed=False to managed=True affect the data ?
I have a large table of a Model that has managed=False and want to add a new field to it. adding a field using migration can't be done without changing the model to managed=True
Is it safe to just change it to managed=True , migrate the change, then update fields ?

Yes. It is safe and required. I have read django documentation about your problem. That says that:
Managed option defaults to True, meaning Django will create the
appropriate database tables in migrate or as part of migrations and
remove them as part of a flush management command. That is, Django
manages the database tables’ lifecycles.
If False, no database table creation, modification, or deletion
operations will be performed for this model.
If your django model option managed=False then make it managed=True, otherwise your migration of models won't work. For more info read django documentation.

Related

How does dependencies isolation between MongoDB and Django work?

How does Isolation dependencies between mongdb and django work?
I have made several projects with JAVA/SPRING, and the recent days,
I am studying Python django .
I successed to get connection between django and sqlite, and few days ago,
when I tried to connect to mongodb, it is hard to seperate dependencies database and django because of django-admin.
Django-admin require to attain specific Fields to each model, however, every database has each their own Field properties. Therefore, when project should change database structure, we should change a lot of code in model.py.
e.g
What if sqlite to Mongodb? only using different driver cannot make server work. e.g models.TextField(sqlite) -> models.StringField(mongodb). It is unavoidable, right? It seems difficult that solating dependencies completely between database and django
Is it Okay? do I miss something?
What if sqlite to Mongodb? only using different driver cannot make server work. e.g models.TextField(sqlite) -> models.StringField(mongodb). It is unavoidable, right? It seems difficult that solating dependencies completely between database and django
TextField and StringField isn't where you will have problems since it is supported in almost all databases, but consider this library django-mongodb-engine, it reuses the basic fields that already exist in Django ORM to the extent of what's possible, e.g.
class Post(models.Model):
title = models.CharField() <-- both Django ORM and mongodb-engine have this
text = models.TextField() <-- both Django ORM and mongodb-engine have this
This model will work as is both in SQL and MongoDB engines, but if you use a MongoDB-only (as in not in default Django ORM engine) feature like ListField()
class Post(models.Model):
title = models.CharField()
text = models.TextField()
tags = ListField() # <-- not supported everywhere
Then you migration to a SQL engine will involve some manual work to map that field.
Therefore, when project should change database structure, we should change a lot of code in models.py. Is it Okay?
Typically yes, to change the database structure you make changes in models.py. After which you would be running a migration, which is a step that generates scripts to alter the database (e.g. adding a new SQL table column). For MongoDB there's no explicit migration, as its schema is flexible (or schemaless if you prefer).
As for the admin, it's fairly smart when it comes to Django models, you may need to define the models and fields you want to appear in the admin, but in the detail view you don't have to worry about every single field, as Django admin understands them based on the information in models.py
And to change database drivers, it's the DATABASES value in settings.py

Edit database outside Django ORM

If one is using Django, what happens with changes made directly to the database (in my case postgres) through either pgadmin or psql?
How are such changes handled by migrations? Do they take precedence over what the ORM thinks the state of affairs is, or does Django override them and impose it's own sense of change history?
Finally, how are any of these issues effected, or avoided, by git, if at all?
Thanks.
You can exclude a model completely from the django migrations, and then you are responsible to adjust the schema to the django code (or the django code to the existing schema):
class SomeModel(models.Model):
class Meta:
managed = False
db_table = "some_table_name"
name = models.Fields....
Note that you can't have it both ways, so migrations are preferred when possible. You can always define a custom SQL migration, that will save the need for external changes. However, sometimes you do need to handle the schema elsewhere instead of migrations, and then use managed=False
The migrations system does not look at your current schema at all. It builds up its picture from the graph of previous migrations and the current state of models.py. That means that if you make changes to the schema from outside this system, it will be out of sync; if you then make the equivalent change in models.py and create migrations, when you run them you will probably get an error.
For that reason, you should avoid doing this. If it's done already, you could apply the conflicting migration in fake mode, which simply marks it as done without actually running the code against the database. But it's simpler to do everything via migrations in the first place.
git has no impact on this at all, other than to reiterate that migrations are code, and should be added to your git repo.

Whether to define own User model in django or use Django auth user model?

I am starting with Django App schema design and my schema has UserProfile, UserFavourites and UserComments models .
After doing a bit research i found out that we can user django's own User model or we can create own user model which will extend from AbstractUser
Platform = Django 1.8.5
I have found many similar questions but now that i have newest version of Django framework has anything changed ?
Also need to know pros and cons of each approach
In a new project, strongly consider starting out with a custom User model.
The reason is that if you want to change your User model later, then there is a clear way to do that (migrations). However, switching from a auth-User to a custom User when you already have ForeignKey relations (etc) to the auth-User is a major pain (see below). Considering that it is very easy to just start out with your own model at the start of a project (maybe just copy the auth model), there is very little reason not to.
The docs say this about how hard it is to change AUTH_USER_MODEL later:
Warning
Changing AUTH_USER_MODEL has a big effect on your database structure.
It changes the tables that are available, and it will affect the
construction of foreign keys and many-to-many relationships. If you
intend to set AUTH_USER_MODEL, you should set it before creating any
migrations or running manage.py migrate for the first time.
Changing this setting after you have tables created is not supported
by makemigrations and will result in you having to manually fix your
schema, port your data from the old user table, and possibly manually
reapply some migrations.
Warning
Due to limitations of Django’s dynamic dependency feature for
swappable models, you must ensure that the model referenced by
AUTH_USER_MODEL is created in the first migration of its app (usually
called 0001_initial); otherwise, you will have dependency issues.
In addition, you may run into a CircularDependencyError when running
your migrations as Django won’t be able to automatically break the
dependency loop due to the dynamic dependency. If you see this error,
you should break the loop by moving the models depended on by your
User model into a second migration (you can try making two normal
models that have a ForeignKey to each other and seeing how
makemigrations resolves that circular dependency if you want to see
how it’s usually done)
In other words, if you choose not to use AUTH_USER_MODEL at the start of your project, it's almost impossible to change later.
There is a ticket #24370 for adding custom user model and AUTH_USER_MODEL setting to the default project template, and to recommend doing this in the documentation. This ticket is just waiting for someone to implement it.
Pulled from Django's documentation
If you wish to store information related to User, you can use a one-to-one relationship to a model containing the fields for additional information. This one-to-one model is often called a profile model, as it might store non-auth related information about a site user
So just add your extra user fields to UserProfile Model. Make a one-to-one relationship with each of your desired model

django: exclude models from migrations

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.

Ignoring existing table when ./manage.py migrate

I have a question about Django's migration feature when there is an existing table.
ContentData
ContentType
Faq
UserLog
TB_TEAM_INF
When I try to do "./manage.py migrate" so it can create the 5 tables above from models.py, I got an error message because there is an existing table, TB_TEAM_INF.
Since TB_TEAM_INF is a table being used by another team, I cannot remove the table. I cannot use a separated database either due to constraints of the project. In this case I open the migration file like 0001_initial.py and manually remove the model object, TB_TEAM_INF temporarily during migration.
Is there a better way to ignore existing tables when "./manage.py migrate" rather than manually editing the migration file?
I tried --exclude=TB_TEAM_INF or --ignore=TB_TEAM_INF option with ./manage.py migrate but it seems those options are not accepted. I am using Django 1.7.2.
Add the managed option to your model definition:
class TB_TEAM_INF(models.Model):
...
class Meta:
managed = False
Excerpt from the documentation:
If False, no database table creation or deletion operations will be performed for this model.

Categories

Resources