Django syncdb doesn't work after invoking inspectdb - django

I created a model from an existing PostgreSql database using inspectdb, when I try to do a syncdb,in order to generate the authorization tables, it generates the following error:
CommandError: One or more models did not validate:
db.t1: "ip": CharFields require a "max_length" attribute that is a positive integer.
So I put the max_length=255 to all CharFields but it doesn't work neither with that. Django version is 1.5.1.
Anyone have an idea how to fix this?

Currently inspectdb doesn't set max_length for PostgreSQL char fields without specified length. FYI, quote from postgreSQL docs:
The notations varchar(n) and char(n) are aliases for character
varying(n) and character(n), respectively. character without length
specifier is equivalent to character(1). If character varying is used
without length specifier, the type accepts strings of any size. The
latter is a PostgreSQL extension.
But, Django doesn't allow to define CharFields without max_length parameter. There is an open ticket for it.
This django snippet provides a custom CharField without length limit - should pass all django's validation.
Also, switching to TextField could help too.
Hope that helps.

Related

Django upgrade filter/prefetch_related behaviour change?

I'm in the process of upgrading from Django 1.8.19 to 1.11.15 and I've found a piece of code which is breaking.
In particular this query is doing something different to what it did before.
project_groups = brand.project_groups.prefetch_related(
'project', 'project__score', 'project__themes').filter(
project=projects
).distinct()
Previously (in Django 1.8), according to the output of "project_groups.query" it produced SQL including:
... projectgroup.project_id IN [projects query]
Now it produces SQL reading:
... projectgroup.project_id = [projects query]
This breaks as the [projects query] returns more than one row. So I get a:
ProgrammingError: more than one row returned by a subquery used as an expression
The only changes I've made to the code for this upgrade are to models and migrations to use ArrayField and HStoreField from django.contrib.postgres.fields instead of the django_hstore equivalents.
My guess is that the original code was wrong, but worked due to a bug in Django (filter/prefetch_related) which has now been fixed. Is that likely to be correct? If this is in fact a new bug in Django I don't want to write code which relies on it!
There was a change to field lookups behaviour of Django between 1.8 and 1.9 that explains this - you can see the details at Django ticket #25284.
In Django 1.8 a query such as Model.objects.filter(related_id = RelatedModel.objects.all()) used to result in an implicit __in lookup so the SQL query contained related_id IN (SELECT id FROM ...). But in Django 1.9 the "IN" is changed to an "=", which causes the query to break in MySql and Postgres. The change was classed a bug fix as the implicit "IN" behaviour was undocumented and probably accidental.
You should be able to fix the query fairly easily by adding an explicit lookup type to the field lookup such as .filter(project__in=projects) - see Django Documentation: Field Lookups

what is no such column: REFERRED.number?

I'm trying to load a fixture and it gives me:
django.db.utils.OperationalError: Problem installing fixtures: no such column: REFERRED.number
Unfortunately, I cannot show the json, because there is all kind of private stuff in there, but I was hoping someone might explain to me what the REFERRED might mean. What kind of error am I looking for?
I made a few migrations and now the DB is out of wack. So the json is slightly off to the DB. There are multiple things called number though. Referred sounds it's some kind of foreignkey error!? Can you give me any hint what to look for?
I had a similar issue and found out what REFERRED was by adding print(query) in django/db/backends/sqlite3/base.py#L297. That showed me all the queries django was running against my sqlite3 database.
In my case, loaddata was not finding the field id (the primary key field that is default in django) for a model in which I had set primary_key=True to one of its fields. Eventhough django was not automatically generating the id field (correct behaviour), loaddata kept looking for the id field. A possible solution would be to add --natural-primary option, but that didn't work for me ATM.
Ref: https://docs.djangoproject.com/en/1.11/topics/serialization/#topics-serialization-natural-keys

Custom index name in South/Django

Is there a way to set our own index name in Django models? Currently, the migration scripts would create a name in format [table_name]_9fcb4ba3 and I'd like to have the name more descriptive, i.e. [table_name]_[column_name] or so.
On the Django's Model Field Reference page, it doesn't seem to have such option (https://docs.djangoproject.com/en/1.8/ref/models/fields/#db-index)
For anyone finding its way from Google - seems Django 1.11 allows you now to have a custom name for indexes. Following the documentation as described here:
Index.name
The name of the index. If name isn’t provided Django will auto-generate a name. For compatibility with different databases, index names cannot be longer than 30 characters and shouldn’t start with a number (0-9) or underscore (_).
There is no way of customizing the name for indexes as these are generated by hashing (the index name calculation uses some hashing techniques)

column "is_superuser" is of type integer but expression is of type boolean DJANGO Error

I could use some help. My python 3.4 Django 1.7.4 site worked fine using sqlite. Now I've moved it to Heroku which uses Postgres. And when I try to create a user / password i get this error:
column "is_superuser" is of type integer but expression is of type boolean
LINE 1: ...15-02-08 19:23:26.965870+00:00', "is_superuser" = false, "us...
^
HINT: You will need to rewrite or cast the expression.
The last function call in the stack trace is:
/app/.heroku/python/lib/python3.4/site-packages/django/db/backends/utils.py in execute
return self.cursor.execute(sql, params) ...
▶ Local vars
I don't have access to the base django code, just the code on my app. So any help getting this to work would be really helpful.
It seems to me that you are using raw SQL queries instead of Django ORM calls and this causes portability issues when you switch database engines. I'd strongly suggest to use ORM if it's possible in your case. If not, then I'd say that you need to detect database engine on your own and construct queries depending on current engine.
In this case you could try to use 0 instead of false, I guess this should work both on SQLite and Postgres.
I was facing the same issue while executing raw sql queries in django but got it resolved by just using True|False to cast boolean expressions instead of 0|1.
Query code block is written below which executes perfectly in django.
cursor.execute(
"insert into userapi_user(email,username,first_name,last_name,mobile_number,password,is_superuser,is_staff,is_active,date_joined)"
"values(%s,%s,%s,%s,%s,%s,False,False,True,%s)",
(email, username, first_name, last_name, mobile_number, password, date)
)
The problem is caused by a variable trying to change data types (i.e. from a char field to date-time) in the migration files. A database like PostgreSQL might not know how to change the variable type.
So, make sure the variable has the same type in all migrations.

Django query returning non-unicode strings?

I'm completely baffled by a problem I found today: I have a PostgreSQL database with tables which are not managed by Django, and completely normal queries via QuerySet on these tables. However, I've started getting Unicode exceptions and when I went digging, I found that my QuerySets are returning non-Unicode strings!
Example code:
d = Document.objects.get(id=45787)
print repr(d.title), type(d.title)
The output of the above statement is a normal string (without the u prefix), followed by a <str> type identifier. What's more, this normal string contains UTF-8 data as expected, in raw byte form! If I call d.title.decode('utf-8'), I get valid Unicode strings!
Even more puzzling, some of the fields work correctly. This same table / model contains another field, html_filename of the same type (TextField) which is returned correctly, as a Unicode string!
I have no special options, the database data is correctly encoded, and I don't even know where to begin searching for a solution. This is Django 1.6.2.
Update:
Database Server encoding is UTF8, as usual, and the data is correctly encoded. This is on PostgreSQL 9.1 on Ubuntu.
Update 2:
I think I may have found the cause, but I don't know why it behaves this way: I thought the database fields were defined with the text type, as usual, but instead they are defined as citext (http://www.postgresql.org/docs/9.1/static/citext.html). Since the Django model is unmanaged, it looks like Django doesn't interpret the field type as being worthy of converting to Unicode. Any ideas how to force Django to do this?
Apparently, Django will not treat fields of type citext as textual and return them as Unicode strings.