Django and read-only database connections - python

Assume a Django application which is supposed to use two MySQL databases:
default - for storing data represented by models A and B (read-write access)
support - for importing data represented by models C and D (read-only access)
The support database is a part of an external application and cannot be modified.
Since the Django application uses the built-in ORM for models A and B I figured it should use the very same ORM for models C and D, even though they map to tables in an external database (support.)
In order to achieve that I defined the models C and D as follows:
from django.db import models
class ExternalModel(models.Model):
class Meta:
managed = False
abstract = True
class ModelC(ExternalModel):
some_field = models.TextField(db_column='some_field')
class Meta(ExternalModel.Meta):
db_table = 'some_table_c'
class ModelD(ExternalModel):
some_other_field = models.TextField(db_column='some_other_field')
class Meta(ExternalModel.Meta):
db_table = 'some_table_d'
Then I defined a database router:
from myapp.myapp.models import ExternalModel
class DatabaseRouter(object):
def db_for_read(self, model, **hints):
if issubclass(model, ExternalModel):
return 'support'
return 'default'
def db_for_write(self, model, **hints):
if issubclass(model, ExternalModel):
return None
return 'default'
def allow_relation(self, obj1, obj2, **hints):
return (isinstance(obj1, ExternalModel) == isinstance(obj2, ExternalModel))
def allow_migrate(self, db, app_label, model_name=None, **hints):
return (db == 'default')
And finally adjusted settings.py:
# (...)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {
'read_default_file': os.path.join(BASE_DIR, 'resources', 'default.cnf'),
},
},
'support': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {
'read_default_file': os.path.join(BASE_DIR, 'resources', 'support.cnf'),
},
},
}
DATABASE_ROUTERS = ['myapp.database_router.DatabaseRouter']
# (...)
The user specified in support.conf for the support database has been assigned read-only privileges.
But when I run python manage.py makemigrations it fails with the following output:
Traceback (most recent call last):
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/backends/utils.py", line 62, in execute
return self.cursor.execute(sql)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/backends/mysql/base.py", line 112, in execute
return self.cursor.execute(query, args)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/cursors.py", line 226, in execute
self.errorhandler(self, exc, value)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorvalue
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/cursors.py", line 217, in execute
res = self._query(query)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/cursors.py", line 378, in _query
rowcount = self._do_query(q)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/cursors.py", line 341, in _do_query
db.query(q)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/connections.py", line 280, in query
_mysql.connection.query(self, query)
_mysql_exceptions.OperationalError: (1142, "CREATE command denied to user 'somedbuser'#'somehost' for table 'django_migrations'")
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/migrations/recorder.py", line 57, in ensure_schema
editor.create_model(self.Migration)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 295, in create_model
self.execute(sql, params or None)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 112, in execute
cursor.execute(sql, params)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/backends/utils.py", line 62, in execute
return self.cursor.execute(sql)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/backends/mysql/base.py", line 112, in execute
return self.cursor.execute(query, args)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/cursors.py", line 226, in execute
self.errorhandler(self, exc, value)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorvalue
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/cursors.py", line 217, in execute
res = self._query(query)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/cursors.py", line 378, in _query
rowcount = self._do_query(q)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/cursors.py", line 341, in _do_query
db.query(q)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/MySQLdb/connections.py", line 280, in query
_mysql.connection.query(self, query)
django.db.utils.OperationalError: (1142, "CREATE command denied to user 'somedbuser'#'somehost' for table 'django_migrations'")
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "manage.py", line 22, in <module>
execute_from_command_line(sys.argv)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/core/management/__init__.py", line 367, in execute_from_command_line
utility.execute()
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/core/management/__init__.py", line 359, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/core/management/base.py", line 305, in run_from_argv
self.execute(*args, **cmd_options)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/core/management/base.py", line 356, in execute
output = self.handle(*args, **options)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/core/management/commands/makemigrations.py", line 100, in handle
loader.check_consistent_history(connection)
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/migrations/loader.py", line 276, in check_consistent_history
applied = recorder.applied_migrations()
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/migrations/recorder.py", line 65, in applied_migrations
self.ensure_schema()
File "/Users/username/Development/stuff/myapp/lib/python3.5/site-packages/django/db/migrations/recorder.py", line 59, in ensure_schema
raise MigrationSchemaMissing("Unable to create the django_migrations table (%s)" % exc)
django.db.migrations.exceptions.MigrationSchemaMissing: Unable to create the django_migrations table ((1142, "CREATE command denied to user 'somedbuser'#'somehost' for table 'django_migrations'"))
It appears that Django tries to create the django_migrations table in the read-only database support nevertheless.
Is there any clean way to prevent the migrations mechanism from attempting that? Or do I have to employ another ORM library for this read-only access to the support database?

I encountered the same issue (using Django 1.11) and this question was at the top of my Google results for it.
Your initial solution is only missing one critical piece. You need to tell Django what database models 'C' and 'D' are using. What worked for me:
class ExternalModel(models.Model):
class Meta:
managed = False
abstract = True
app_label = 'support'
Then tell your database router how to behave when it encounters that app_label in the allow_migrate() section:
def allow_migrate(self, db, app_label, model_name=None, **hints):
if app_label == 'support':
return False
return (db == 'default')
I'm not sure that is the most-correct-solution in the eyes of the Django team, but effect is allow_migrate() returning False for any models defined with that app_label attribute value.
The Django documentation on routers doesn't mention this explicitly (or, at least with model code samples that make it clear how the ORM passes the value for 'db' to allow_migrate()), but between the 'app_label' and 'managed' attributes you can get it to work*.
* In my case the default is postgres and the read-only database is Oracle 12 via cx_Oracle.

It seems around the Django 1.10.1 timeframe, Tim Graham (the primary Django maintainer), accepted a patch that suppressed this specific exception but later withdrew the patch in favor of (roughly) the following method to work around this issue and to support read-only databases using the Django ORM.
Define a database router as described in the Django documentation
on routers I've attached an example router below that routes to a
different database based on an 'app' flag in the model meta.
In your routers allow_migrations method, return False for any db argument
that corresponds to a read-only database. This prevents the migration of
the model tables regardless of where they would be routed to.
This next part is a little weird but where the rubber hits the road and
actually answers the original question. To keep makemigrations from
attempting to create the django_migrations table in your read-only
database, the database traffic should not be routed. In the example
router, that means 'read_only' is not in DATABASE_APPS_MAPPING.
So, instead, Read-only databases are accessed explicitly with "using" (e.g. MyReadOnlyModel.objects.using('read_only').all()
Django database apps router

Had the same problem.
Django is trying to create the 'django_migrations' table in all DBs.
This happens even if there are no models associated with the read-only DB
and all routers are pointing a different DB.
I also ended up using peewee.

Related

How to access tables from a different schema in oracle 11g using django?

I have a user named mi_abc in oracle 11g.
The user do not have any table in the database but has access to all the tables in another schema sch_abc.
When I run a normal select query from sqldeveloper on the sch_abc schema from mi_abc, it works perfectly fine, but when I use django, I am always getting the error:-
django.db.utils.DatabaseError: ORA-00942: table or view does not exist
I tried to set the db_table = sch_abc.tableName and also set db_table = tableName but both gives me the same error. Any clue how to resolve this?
TRACE:-
Traceback (most recent call last):
File "C:\xxx\xxx\xxx\xxx\xxx\xxx\xxxx\lib\site-packages\django\core\handlers\exception.py", line 41, in inner
response = get_response(request)
File "C:\xxx\xxx\xxxx\xxxx\xxxx\Python\Python37\lib\site-packages\django\utils\deprecation.py", line 142, in __call__
response = self.process_response(request, response)
File "C:\xxxx\xxxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\contrib\sessions\middleware.py", line 58, in process_response
request.session.save()
File "C:\xxx\xxxx\xxxx\xxxx\xxxxx\Python\Python37\lib\site-packages\django\contrib\sessions\backends\db.py", line 81, in save
return self.create()
File "C:\xxxx\xxxxx\xxxx\xxxx\xxxxx\Python\Python37\lib\site-packages\django\contrib\sessions\backends\db.py", line 50, in create
self._session_key = self._get_new_session_key()
File "C:\xxxx\xxxxx\xxxxx\xxxxx\xxxx\Python\Python37\lib\site-packages\django\contrib\sessions\backends\base.py", line 164, in _get_new_session_key
if not self.exists(session_key):
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\contrib\sessions\backends\db.py", line 46, in exists
return self.model.objects.filter(session_key=session_key).exists()
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\query.py", line 673, in exists
return self.query.has_results(using=self.db)
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\sql\query.py", line 517, in has_results
return compiler.has_results()
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\sql\compiler.py", line 858, in has_results
return bool(self.execute_sql(SINGLE))
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\sql\compiler.py", line 899, in execute_sql
raise original_exception
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\models\sql\compiler.py", line 889, in execute_sql
cursor.execute(sql, params)
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\utils\six.py", line 685, in reraise
raise value.with_traceback(tb)
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\backends\utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "C:\xxx\xxx\xxx\xxx\xxx\Python\Python37\lib\site-packages\django\db\backends\oracle\base.py", line 497, in execute
return self.cursor.execute(query, self._param_generator(params))
django.db.utils.DatabaseError: ORA-00942: table or view does not exist
Well, I resolved the issue and let me tell you there is no straight way to do it in django. The problem with my application was, I was using the authetication features of django and also session handling. All these tables are created by django directly on the initial migration. So, there is no existence of them in the models.py file that you can simply append the schema name and ask your application to connect to the table of that schema.
What I ended up doing is, I created private synonyms to all the tables of the other schema which actually contained those tables. If you do this, you don't have to change anything in your django code. Your application will simply work because oracle will do the dirty work of actually connecting to the proper table. You will merely call the table in your application as if its your own. In this way when django looks for tables like django_session, auth_user etc, it simply queries it like it always does and oracle redirects it to the actual tables present in another schema.
Hope this helps people who face this issue in the future.
This is by no means officially supported, but this works in Postgres:
class Meta:
managed = False
db_table = 'schema\".\"table'
It took some trial and error for Postgres, but you can probably do something similar for Oracle. This is because the Postgres engine quotes object names, and this fakes the quoting mechanism out.
UPDATE:
After doing some digging, I found this for Oracle (modified for Python 3):
class Meta:
db_table = '"SCHEMA"."TABLE_NAME"'
Source: https://code.djangoproject.com/ticket/14136
I would recommend keeping managed = False unless you really know what you're doing. Good luck!
You can set the required schema, before executing the command. and then go back to public schema once the queryset is processed.
from django.db import connection
connection.set_schema(schema_name)

Django Models Relations to User Model

I'm new to the forum and I've got a problem.
in Django im trying to create a UserProfile class by referencing it via a OnetoOneField to an User Object. When i try to migrate, I get:
"You are trying to add a non-nullable field 'id' to author without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py"
I understand, that there are some fields in the User model (for example "id") that are not allowed to be null.
When I try to set a default it will makemigrations, but migrate fails with a syntax error.
My Question is how do I allow Null, or set a default that works, without writing a custom User class, and is that even possible ?
I'd really appreciate any help with this.
Here is my Code:
from django.db import models
from django.contrib.auth.models import User as User_django
class User(User_django):
pass
class Author(models.Model):
user = models.OneToOneField(User, null=True)
class BaseElement(models.Model):
author=models.ForeignKey(Author, null=True)
upvotes = models.PositiveIntegerField(default=0)
downvotes = models.PositiveIntegerField(default=0)
created = models.DateTimeField(auto_now_add=True, null=True)
def vote_up(self):
self.upvotes.value = self.upvotes.value + 1
def vote_down(self):
self.downvotes.value = self.downvotes.value + 1
class Meta:
abstract = True
class Post(BaseElement):
content = models.TextField(max_length=240)
tags = models.CharField(max_length=40, blank=True)
said_by = models.CharField(max_length=40)
said_at = models.CharField(max_length=40, blank=True)
def get_comments(self):
return self.comment_set.all()
def get_comments_anzahl(self):
return self.comment_set.all().count()
class Comment(BaseElement):
content = models.TextField(max_length=140)
commented_post = models.ForeignKey(Post, related_query_name="comment", null=True)
EDIT:
This happens if I try to set a default and try to migrate:
You are trying to add a non-nullable field 'id' to author without a
default; we can't do that (the database needs something to populate
existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows)
2) Quit, and let me add a default in models.py
Select an option: 1
Please enter the default value now, as valid Python
The datetime and django.utils.timezone modules are available, so you can
do e.g. timezone.now()
>>> 1
Migrations for 'post':
0003_auto_20160505_1237.py:
- Change Meta options on author
- Change managers on author
- Remove field user_ptr from author
- Add field id to author
- Add field user to author
Operations to perform:
Apply all migrations: contenttypes, admin, sessions, post, auth
Running migrations:
Rendering model states... DONE
Applying post.0003_auto_20160505_1237...Traceback (most recent call last):
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
sqlite3.OperationalError: near ")": syntax error
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django /core/management/__init__.py", line 353, in execute_from_command_line
utility.execute()
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/__init__.py", line 345, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/base.py", line 348, in run_from_argv
self.execute(*args, **cmd_options)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/base.py", line 399, in execute
output = self.handle(*args, **options)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/core/management/commands/migrate.py", line 200, in handle
executor.migrate(targets, plan, fake=fake, fake_initial=fake_initial)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 92, in migrate
self._migrate_all_forwards(plan, full_plan, fake=fake, fake_initial=fake_initial)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 121, in _migrate_all_forwards
state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/executor.py", line 198, in apply_migration
state = migration.apply(state, schema_editor)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/migration.py", line 123, in apply
operation.database_forwards(self.app_label, schema_editor, old_state, project_state)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/migrations/operations/fields.py", line 121, in database_forwards
schema_editor.remove_field(from_model, from_model._meta.get_field(self.name))
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 247, in remove_field
self._remake_table(model, delete_fields=[field])
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/schema.py", line 197, in _remake_table
self.quote_name(model._meta.db_table),
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/base/schema.py", line 110, in execute
cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 79, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/utils.py", line 95, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
raise value.with_traceback(tb)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/utils.py", line 64, in execute
return self.cursor.execute(sql, params)
File "/home/jaidmin/.conda/envs/cyf/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 323, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.OperationalError: near ")": syntax error
EDIT:
It seems like I solved it by creating a new project and step by step copying the models and migrating. Still wondering what was going on there, because I flushed the database and deleted the migration files multiple times and it was still throwing errors.
Thanks for the help !
Take a look at this:
https://docs.djangoproject.com/es/1.9/topics/db/examples/one_to_one/
Your code is a ONE-to-ONE with user. When you set it, it implies CASCADE delete, and therefore can never be null.
if you change to One-to-Many, and just ensure that you only insert one object for the foreign key, it'll work. Otherwise, change your cascade rule.
I will say, however, that's not a good idea, because if you make it null, what separates it from other records. Consider a second PK field.
Best of luck.
Just import django's built-in User model like this:
from django.contrib.auth.models import User
and delete this line:
class User(User_django):
pass
from your code as it is completely unnecessary.
UPDATE: Also it looks like your problem has nothing to do with the User model. I think somehow you added an id field to your Author model and deleted it (maybe after an unsuccessful migration). If this is the case, then you could edit your 0003_auto_20160505_1237.py. To do that open it and remove the lines which look something like this:
migrations.AddField(
model_name='author',
name='id',
field=models.someFieldType(options)),
),
and try again.

python3 manage.py migrate exceptions

I am new to django 1.7 and python3. I am using OSX. As I was following the django 1.7 documentation online,
I tried
python3 manage.py migrate
and it resulted
Operations to perform:
Apply all migrations: auth, contenttypes, sessions, admin
Running migrations:
No migrations to apply.
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/contrib/contenttypes/models.py", line 44, in get_for_model
ct = self._get_from_cache(opts)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/contrib/contenttypes/models.py", line 34, in _get_from_cache
return self.__class__._cache[self.db][key]
KeyError: 'default'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/backends/mysql/base.py", line 128, in execute
return self.cursor.execute(query, args)
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/cursors.py", line 184, in execute
self.errorhandler(self, exc, value)
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/connections.py", line 37, in defaulterrorhandler
raise errorvalue
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/cursors.py", line 171, in execute
r = self._query(query)
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/cursors.py", line 330, in _query
rowcount = self._do_query(q)
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/cursors.py", line 294, in _do_query
db.query(q)
_mysql_exceptions.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s AND `django_content_type`.`model` = %s) LIMIT 21' at line 1")
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/contrib/contenttypes/models.py", line 50, in get_for_model
defaults={'name': smart_text(opts.verbose_name_raw)},
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/models/manager.py", line 92, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/models/query.py", line 422, in get_or_create
return self.get(**lookup), False
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/models/query.py", line 351, in get
num = len(clone)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/models/query.py", line 122, in __len__
self._fetch_all()
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/models/query.py", line 966, in _fetch_all
self._result_cache = list(self.iterator())
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/models/query.py", line 265, in iterator
for row in compiler.results_iter():
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/models/sql/compiler.py", line 700, in results_iter
for rows in self.execute_sql(MULTI):
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/models/sql/compiler.py", line 786, in execute_sql
cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/backends/utils.py", line 81, in execute
return super(CursorDebugWrapper, self).execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/utils.py", line 94, in __exit__
six.reraise(dj_exc_type, dj_exc_value, traceback)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/utils/six.py", line 549, in reraise
raise value.with_traceback(tb)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/backends/utils.py", line 65, in execute
return self.cursor.execute(sql, params)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/db/backends/mysql/base.py", line 128, in execute
return self.cursor.execute(query, args)
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/cursors.py", line 184, in execute
self.errorhandler(self, exc, value)
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/connections.py", line 37, in defaulterrorhandler
raise errorvalue
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/cursors.py", line 171, in execute
r = self._query(query)
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/cursors.py", line 330, in _query
rowcount = self._do_query(q)
File "/Users/NAME/Library/Python/3.4/lib/python/site-packages/MySQLdb/cursors.py", line 294, in _do_query
db.query(q)
django.db.utils.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '%s AND `django_content_type`.`model` = %s) LIMIT 21' at line 1")
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "manage.py", line 10, in <module>
execute_from_command_line(sys.argv)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
utility.execute()
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/core/management/__init__.py", line 377, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/core/management/base.py", line 288, in run_from_argv
self.execute(*args, **options.__dict__)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/core/management/base.py", line 338, in execute
output = self.handle(*args, **options)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/core/management/commands/migrate.py", line 164, in handle
emit_post_migrate_signal(created_models, self.verbosity, self.interactive, connection.alias)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/core/management/sql.py", line 268, in emit_post_migrate_signal
using=db)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/dispatch/dispatcher.py", line 198, in send
response = receiver(signal=self, sender=sender, **named)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/contrib/auth/management/__init__.py", line 83, in create_permissions
ctype = ContentType.objects.db_manager(using).get_for_model(klass)
File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/contrib/contenttypes/models.py", line 58, in get_for_model
" is migrated before trying to migrate apps individually."
RuntimeError: Error creating new content types. Please make sure contenttypes is migrated before trying to migrate apps individually.`
I don't know what it means and I am sure it is not right.
Is the migration successful?
Please help. Thanks
Here is my /Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/site-packages/django/contrib/contenttypes/models.py
from __future__ import unicode_literals
from django.apps import apps
from django.db import models
from django.db.utils import OperationalError, ProgrammingError
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_text, force_text
from django.utils.encoding import python_2_unicode_compatible
class ContentTypeManager(models.Manager):
# Cache to avoid re-looking up ContentType objects all over the place.
# This cache is shared by all the get_for_* methods.
_cache = {}
def get_by_natural_key(self, app_label, model):
try:
ct = self.__class__._cache[self.db][(app_label, model)]
except KeyError:
ct = self.get(app_label=app_label, model=model)
self._add_to_cache(self.db, ct)
return ct
def _get_opts(self, model, for_concrete_model):
if for_concrete_model:
model = model._meta.concrete_model
elif model._deferred:
model = model._meta.proxy_for_model
return model._meta
def _get_from_cache(self, opts):
key = (opts.app_label, opts.model_name)
return self.__class__._cache[self.db][key]
def get_for_model(self, model, for_concrete_model=True):
"""
Returns the ContentType object for a given model, creating the
ContentType if necessary. Lookups are cached so that subsequent lookups
for the same model don't hit the database.
"""
opts = self._get_opts(model, for_concrete_model)
try:
ct = self._get_from_cache(opts)
except KeyError:
try:
ct, created = self.get_or_create(
app_label=opts.app_label,
model=opts.model_name,
defaults={'name': smart_text(opts.verbose_name_raw)},
)
except (OperationalError, ProgrammingError):
# It's possible to migrate a single app before contenttypes,
# as it's not a required initial dependency (it's contrib!)
# Have a nice error for this.
raise RuntimeError(
"Error creating new content types. Please make sure contenttypes" +
" is migrated before trying to migrate apps individually."
)
self._add_to_cache(self.db, ct)
return ct
def get_for_models(self, *models, **kwargs):
"""
Given *models, returns a dictionary mapping {model: content_type}.
"""
for_concrete_models = kwargs.pop('for_concrete_models', True)
# Final results
results = {}
# models that aren't already in the cache
needed_app_labels = set()
needed_models = set()
needed_opts = set()
for model in models:
opts = self._get_opts(model, for_concrete_models)
try:
ct = self._get_from_cache(opts)
except KeyError:
needed_app_labels.add(opts.app_label)
needed_models.add(opts.model_name)
needed_opts.add(opts)
else:
results[model] = ct
if needed_opts:
cts = self.filter(
app_label__in=needed_app_labels,
model__in=needed_models
)
for ct in cts:
model = ct.model_class()
if model._meta in needed_opts:
results[model] = ct
needed_opts.remove(model._meta)
self._add_to_cache(self.db, ct)
for opts in needed_opts:
# These weren't in the cache, or the DB, create them.
ct = self.create(
app_label=opts.app_label,
model=opts.model_name,
name=smart_text(opts.verbose_name_raw),
)
self._add_to_cache(self.db, ct)
results[ct.model_class()] = ct
return results
def get_for_id(self, id):
"""
Lookup a ContentType by ID. Uses the same shared cache as get_for_model
(though ContentTypes are obviously not created on-the-fly by get_by_id).
"""
try:
ct = self.__class__._cache[self.db][id]
except KeyError:
# This could raise a DoesNotExist; that's correct behavior and will
# make sure that only correct ctypes get stored in the cache dict.
ct = self.get(pk=id)
self._add_to_cache(self.db, ct)
return ct
def clear_cache(self):
"""
Clear out the content-type cache. This needs to happen during database
flushes to prevent caching of "stale" content type IDs (see
django.contrib.contenttypes.management.update_contenttypes for where
this gets called).
"""
self.__class__._cache.clear()
def _add_to_cache(self, using, ct):
"""Insert a ContentType into the cache."""
# Note it's possible for ContentType objects to be stale; model_class() will return None.
# Hence, there is no reliance on model._meta.app_label here, just using the model fields instead.
key = (ct.app_label, ct.model)
self.__class__._cache.setdefault(using, {})[key] = ct
self.__class__._cache.setdefault(using, {})[ct.id] = ct
#python_2_unicode_compatible
class ContentType(models.Model):
name = models.CharField(max_length=100)
app_label = models.CharField(max_length=100)
model = models.CharField(_('python model class name'), max_length=100)
objects = ContentTypeManager()
class Meta:
verbose_name = _('content type')
verbose_name_plural = _('content types')
db_table = 'django_content_type'
ordering = ('name',)
unique_together = (('app_label', 'model'),)
def __str__(self):
# self.name is deprecated in favor of using model's verbose_name, which
# can be translated. Formal deprecation is delayed until we have DB
# migration to be able to remove the field from the database along with
# the attribute.
#
# We return self.name only when users have changed its value from the
# initial verbose_name_raw and might rely on it.
model = self.model_class()
if not model or self.name != model._meta.verbose_name_raw:
return self.name
else:
return force_text(model._meta.verbose_name)
def model_class(self):
"Returns the Python model class for this type of content."
try:
return apps.get_model(self.app_label, self.model)
except LookupError:
return None
def get_object_for_this_type(self, **kwargs):
"""
Returns an object of this type for the keyword arguments given.
Basically, this is a proxy around this object_type's get_object() model
method. The ObjectNotExist exception, if thrown, will not be caught,
so code that calls this method should catch it.
"""
return self.model_class()._base_manager.using(self._state.db).get(**kwargs)
def get_all_objects_for_this_type(self, **kwargs):
"""
Returns all objects of this type for the keyword arguments given.
"""
return self.model_class()._base_manager.using(self._state.db).filter(**kwargs)
def natural_key(self):
return (self.app_label, self.model)
I believe it is the dependency with mysql. After I switched to postgresql, everything is solved. I found the connector of python with mysql is only up to python 3.3 and I am using python3.4. That is probably the reason and I could not find a connector for mysql and python 3.4.
I assume that there could be some problems with the dependencies.
Instead of running:
python3 manage.py migrate
try with:
python manage.py makemigrations yourapp
python manage.py migrate
if this doesn't work go with:
python manage.py syncdb --all

IntegrityError at non-existing field

I'm having troubles with adding new copy of existing model Clients, which looks like:
class Client(models.Model):
user = models.OneToOneField(User) # Extending default user model
organization = models.CharField(max_length=40)
def __unicode__(self):
return self.user.first_name + " " + self.user.last_name
Im entering shell and type this:
from django.contrib.auth.models import User
from mysiteApp.models import Client
user = User.objects.get(pk=2) # User with pk 2 exists
client = Client(user=user, organization="someorg") # copy creates succesfully
But then, im trying to save copy by
client.save()
And im getting this:
>>> client.save()
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 537, in save
force_update=force_update, update_fields=update_fields)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/base.py", line 641, in save_base
result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/manager.py", line 215, in _insert
return insert_query(self.model, objs, fields, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/query.py", line 1559, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "/usr/local/lib/python2.7/dist-packages/django/db/models/sql/compiler.py", line 844, in execute_sql
cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/util.py", line 41, in execute
return self.cursor.execute(sql, params)
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/sqlite3/base.py", line 389, in execute
six.reraise(utils.IntegrityError, utils.IntegrityError(*tuple(e.args)), sys.exc_info()[2])
File "/usr/local/lib/python2.7/dist-packages/django/db/backends/sqlite3/base.py", line 387, in execute
return Database.Cursor.execute(self, query, params)
IntegrityError: mysiteApp_client.cID may not be NULL
The thing is that i HAD such field as cID in Client model before, wich really had NOT NULL, but now i dont
manage.py sql mysiteApp shows:
BEGIN;
CREATE TABLE "mysiteApp_client" (
"id" integer NOT NULL PRIMARY KEY,
"user_id" integer NOT NULL UNIQUE REFERENCES "auth_user" ("id"),
"organization" varchar(40) NOT NULL
)
;
manage.py syncdb changes nothing, what should i do?
Thanks.
Your database is still in the state as where the cID field is required. This is because syncdb does not alter already existing tables.
To overcome your problem you have three options:
a) delete the Client table (=lose your data) in your database and run syncdb again
b) manually modifying your database using a sql ALTER TABLE command
c) use a migration tool like South (introduction) to reflect the changes you did for models.py in your database. I would recommend to learn how to deal with South, as once you are in production you probably need such a migration tool.

South migration fails

I have a problem with south migrations. I still don't understand how this did happen, and what should what path to move to resolve this
Romans-MacBook-Pro:holms$ ./manage.py migrate
cRunning migrations for accounts:
- Nothing to migrate.
- Loading initial data for accounts.
No fixtures found.
Running migrations for allocations:
- Nothing to migrate.
- Loading initial data for allocations.
No fixtures found.
Running migrations for adyen:
- Nothing to migrate.
- Loading initial data for adyen.
No fixtures found.
Running migrations for blog:
- Nothing to migrate.
- Loading initial data for blog.
No fixtures found.
Running migrations for offers:
- Nothing to migrate.
- Loading initial data for offers.
No fixtures found.
Running migrations for orders:
- Migrating forwards to 0011_update_price_fields.
> orders:0002_update_order_contact_information
Traceback (most recent call last):
File "./manage.py", line 15, in <module>
execute_manager(settings)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 438, in execute_manager
utility.execute()
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/core/management/base.py", line 220, in execute
output = self.handle(*args, **options)
File "/Users/holms/Development/xxx/xxx/settings/../../lib/south/management/commands/migrate.py", line 105, in handle
ignore_ghosts = ignore_ghosts,
File "/Users/holms/Development/xxx/xxx/settings/../../lib/south/migration/__init__.py", line 191, in migrate_app
success = migrator.migrate_many(target, workplan, database)
File "/Users/holms/Development/xxx/xxx/settings/../../lib/south/migration/migrators.py", line 221, in migrate_many
result = migrator.__class__.migrate_many(migrator, target, migrations, database)
File "/Users/holms/Development/xxx/xxx/settings/../../lib/south/migration/migrators.py", line 292, in migrate_many
result = self.migrate(migration, database)
File "/Users/holms/Development/xxx/xxx/settings/../../lib/south/migration/migrators.py", line 125, in migrate
result = self.run(migration)
File "/Users/holms/Development/xxx/xxx/settings/../../lib/south/migration/migrators.py", line 99, in run
return self.run_migration(migration)
File "/Users/holms/Development/xxx/xxx/settings/../../lib/south/migration/migrators.py", line 81, in run_migration
migration_function()
File "/Users/holms/Development/xxx/xxx/settings/../../lib/south/migration/migrators.py", line 57, in <lambda>
return (lambda: direction(orm))
File "/Users/holms/Development/xxx/migrations/0002_update_order_contact_information.py", line 29, in forwards
for o in orders:
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 107, in _result_iter
self._fill_cache()
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 772, in _fill_cache
self._result_cache.append(self._iter.next())
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/query.py", line 273, in iterator
for row in compiler.results_iter():
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 680, in results_iter
for rows in self.execute_sql(MULTI):
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/models/sql/compiler.py", line 735, in execute_sql
cursor.execute(sql, params)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/util.py", line 34, in execute
return self.cursor.execute(sql, params)
File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 234, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.DatabaseError: no such column: orders_order.pre_paid
part of migration file [0002_update_order_contact_information.py] which breaks:
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(DataMigration):
def forwards(self, orm):
Order = models.get_model('orders', 'Order')
orders = Order.all_objects.select_related('buyer')
orders = orders.filter(first_name__isnull=True)
orders = orders.filter(buyer__isnull=False)
orders = orders.exclude(payment_status="UNFINISHED")
userfields = (
'gender', 'birth_date', 'first_name', 'last_name', 'street_number',
You should not interact with your models directly like that. You use django.models, but that version of the models are in a wrong state. You want the state of the models as they were in migration 0002. The south manual states that you should access your models through the orm parameter.
Notice that we use orm.User to access the User model - this gives us the version of User from when this migration was created, so if we want to run the migration in future, it won’t get a completely different, new, User model. source
So you should rewrite the migration like this:
orders = orm.Order.objects.all()
Or even like this:
Order = orm.Order

Categories