Exclude database from django migrations - django

Is there a way to exclude database from django migrations?
I have a sphinxsearch database in my django project:
DATABASES['sphinxsearch'] = {
'ENGINE': 'sphinxsearch.backend.sphinx',
...
}
And when I try to run manage.py makemigrations command, Django tries to run
SHOW FULL TABLES query against it
which leads to an error, because this is wrong syntax for sphinxql
File "C:\Anaconda\lib\site-packages\django\db\backends\mysql\introspection.py", line 56, in get_table_list
cursor.execute("SHOW FULL TABLES")
...
django.db.utils.ProgrammingError: (1064, "sphinxql: syntax error, unexpected IDENT, expecting VARIABLES near 'FULL TABLES'")

An exception to this rule is the makemigrations command.
It validates the migration history in the databases to catch problems with the existing migration files (which could be caused by editing them) before creating new migrations.
By default, it checks only the default database, but it consults the allow_migrate() method of routers if any are installed.
makemigrations always creates migrations for model changes, but if allow_migrate() returns False, any migration operations for the model_name will be silently skipped when running migrate on the db.
Changing the behavior of allow_migrate() for models that already have migrations may result in broken foreign keys, extra tables, or missing tables. When makemigrations verifies the migration history, it skips databases where no app is allowed to migrate.

class DBMigrateRouter(object):
"""
A router to control all database operations on models in the
auth application.
"""
def allow_migrate(self, db, app_label, model_name=None, **hints):
"""
Allows migration for default DB
"""
return db == 'default'
Add this class to settings file
DATABASE_ROUTERS = ['path.to.DBMigrateRouter']
This will skip migrations on databases other than "default".

Related

Django change Migration table name in DB

How can I custom the django_migrations table name?
Even I edit the
venv.lib.site-packages.django.db.migrations.recorder > MigrationRecorder > meta = db_table = "ABC_django_migrations"
the makemigrations cannot detect the changes.
I am using Django version: 3.0.5
Django migrations don't look for changes in its own migration model
MigrationExecutor just ensures that following table exists in database
def migrate(self, targets, plan=None, state=None, fake=False, fake_initial=False):
self.recorder.ensure_schema()
....
where ensure_schema() just creates the table
def ensure_schema(self):
"""Ensure the table exists and has the correct schema."""
# If the table's there, that's fine - we've never changed its schema
# in the codebase.
if self.has_table():
return
# Make the table
try:
with self.connection.schema_editor() as editor:
editor.create_model(self.Migration)
except DatabaseError as exc:
raise MigrationSchemaMissing("Unable to create the django_migrations table (%s)" % exc)
you can manually make migration to edit this model ( AlterModelTable or custom sql) but I would not advise changing anything regarding migrations
How I solve this problem:
Install the app
pip install django-db-prefix
Include the apps in Settings.py
INSTALLED_APPS = ['django_db_prefix',]
Adding the prefix in Settings.py
DB_PREFIX = "foo_"

how to switch to a new database

I want to deploy my django project to the production environments, and associated it with an new empty database, and I did as follows :
Create an new empty database
Updated settings.py and pointed the database name to the new one
Deleted the migrations folder under my App
Run python manage.py runserver and no errors returned
Run python manage.py makemigrations and python manage.py migrate
but only auth related tables created ( like auth_user , auth_group ... ), no databases tables created for my Apps
How should I do for this situation to move to the new database for my project?
Deleted the migrations folder under my App
This was your mistake, you deleted the migrations - including the initial migrations. So when you go to makemigrations you haven't got the initial migration available.
So you need to run makemigrations <app_name> to at least get the initial migration.
If you were to do this again, don't delete the migrations, just change the database settings and then migrate.
Firstly, you should not have deleted the migrations. Now, make all the migrations again which you have deleted.
python manage.py makemigrations app_name
Do this for all the apps of which you have deleted the migrations.
Now, add your new database to settings.py. Do not remove the old one yet. For example, if I were adding a MySQL database, I would have added the following to the DATABASES dictionary in settings.py:
'new': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'databasename',
'USER': 'databaseusername',
'PASSWORD': 'databasepassword',
'HOST': 'localhost',
'PORT': '3306',
}
I have named the database as 'new'. Now we have two databases 'default' and 'new'. Now you have to create tables in the new database by running the migrations on the new database:
python manage.py migrate --database=new
You can follow these additional steps if you want to transfer your data to the new database. First, clear the new database:
python manage.py flush --database=new
Now export data from the old database into a json file:
python manage.py dumpdata>data.json
Import this data into the new database:
python manage.py loaddata data.json --database=new
Now you can remove the 'default' database and rename the 'new' database to 'default'.
The procedure mentioned in this answer is taken from my blog.
Just check the output of python manage.py makemigrations command, if it is showing no change detected then you need to check that have you added that app in your INSTALLED_APPS = [] in settings.py file or it might be the problem because you have deleted migration folder.Because if is there any database connectivity error it will show you that while doing makemigrations.
If your database has a new name, i.e. not "default", you need to specify it to migrate:
python manage.py migrate --database <newdb>

Django 1.8, syncdb not working, throwing a foreign key constraint error

Since I upgrade to Django 1.8 from 1.7, I have got this foreign key constraint error.
File "c:project\env\lib\site-packages\mysql_python-1.2.5-py2.7-win32.egg/MySQLdb\connections.py line 36, in defaulterrorhandler raise errorclass, errorvalue,
Django.db.utils.IntergrityError: 'Cannot add foreing key contraint
What's some wrong with django 1.8 (latest version)?
Try this
DATABASES = {
'default': {
...
'OPTIONS': {
"init_command": "SET foreign_key_checks = 0;",
},
'STORAGE_ENGINE': 'MyISAM / INNODB / ETC'
}
}
Have you created migrations for all your apps? If not, you may well be hitting the problem that the database tables are being created in the wrong order, which will give you this error.
If you have an existing Django 1.7 project, then you need to create the initial migration files, and then fake the initial migration, as described here
https://docs.djangoproject.com/en/1.8/topics/migrations/#adding-migrations-to-apps
Create the migration with
$ python manage.py make migrations your_app_label
And then fake the application
$ python manage.py migrate --fake-initial your_app_label

App tables not created when running test

When i run my app test django don't create my app tables and throw an error.
My test file:
from django.test import TestCase
class MyTest(TestCase):
fixtures = ['initial_data.json']
def test_my_stuff(self):
[...]
When i run test:
DatabaseError: Problem installing fixture
'/home/.../djStock/stock/fixtures/initial_data.json': Could
not load stock.Provider(pk=1): (1146, "Table
'test_djstock.stock_provider' doesn't exist")
My app is correctly added in INSTALLED_APPS. What i miss ?
Must be have south migration files. Check if myapp/migration/ contain files for migration.
You have to comment out 'south' in INSTALLED_APPS before running any tests, otherwise if models are updated, you Django won't have the update reflected in the table creation, thus you get the error that table does not exist.
Assuming you are using Django 1.6.

Django db Table delete

With what command can I delete tables from a django db of a specific app/ only one table?
I did find all sorts of things, but not how to get rid of a table.
Also while I am at this.
I create the models and hit syncdb and then I have the tables.
If I want to update/add to those tables, do I run into problems?
Your best bet would be to get django-south installed in your machine.
if you are using pip, do pip install django-south
This allows you too migrate data forward and backwards.
This is very handy especially if you need to update tables, and new tables etc.
check it out.
adding south to apps are as easy as python manage.py schemamigration appname --initial
Make your changes in a model and run the following python manage.py schemamigration appname --auto
Once your data migration file has been created it'll tell you data is now ready to migrate.
Simply use python manage.py migrate appname
http://south.aeracode.org/docs/about.html
Hope this helps
If you are deleting a table, this is done in the model file of the specific app that you are trying to delete, there is no command for this, you just go into the file and delete it and then re-run syncdb, for your other question, the answer is the same.. every app folder should have a file called "models.py" and here is where the models which are, in this case, equivalent to tables are specified, along with their fields, you simply edit this to make any changes.
def reset():
import install
from django.db.models import get_models
removed_tables = []
exceptions = []
for model in get_models():
if model.__name__ not in ('User','Session','Group','Permission'):
try:
model.objects.all().delete() # So we can remove the table without complaints from the database server.
CURSOR.execute('DROP TABLE %s' % model._meta.db_table)
print "Dropped table %s from model %s" % (model._meta.db_table, model.__name__)
except Exception as e:
exceptions.append([model._meta.db_table, str(e)])
continue
removed_tables.append(model._meta.db_table)
print "Removed %s tables" % len(removed_tables)
syncdb()
install.install() # A function that leads to the creation of my default data