taylorallred
Soy muy nuevo en django y pude terminar el tutorial en djangoproject.com sin ningún error. Ahora estoy revisando el tutorial del marco Django REST que se encuentra en http://www.django-rest-framework.org/
Casi he terminado con él y acabo de agregar autenticación. Ahora estoy recibiendo:
OperationalError at /snippets/
no such column: snippets_snippet.owner_id
Request Method: GET
Request URL: http://localhost:8000/snippets/
Django Version: 1.7
Exception Type: OperationalError
Exception Value:
no such column: snippets_snippet.owner_id
Exception Location: /Users/taylorallred/Desktop/env/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py in execute, line 485
Python Executable: /Users/taylorallred/Desktop/env/bin/python
Python Version: 2.7.5
Python Path:
['/Users/taylorallred/Desktop/tutorial',
'/Users/taylorallred/Desktop/env/lib/python27.zip',
'/Users/taylorallred/Desktop/env/lib/python2.7',
'/Users/taylorallred/Desktop/env/lib/python2.7/plat-darwin',
'/Users/taylorallred/Desktop/env/lib/python2.7/plat-mac',
'/Users/taylorallred/Desktop/env/lib/python2.7/plat-mac/lib-scriptpackages',
'/Users/taylorallred/Desktop/env/Extras/lib/python',
'/Users/taylorallred/Desktop/env/lib/python2.7/lib-tk',
'/Users/taylorallred/Desktop/env/lib/python2.7/lib-old',
'/Users/taylorallred/Desktop/env/lib/python2.7/lib-dynload',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
'/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
'/Users/taylorallred/Desktop/env/lib/python2.7/site-packages']
Server time: Sat, 11 Oct 2014 07:02:34 +0000
He buscado en varios lugares en la web, no solo en StackOverflow para encontrar la solución, parece que, en general, el problema está en mi base de datos y necesito eliminarla y luego rehacerla, lo he hecho varias veces, el tutorial incluso me tiene elimine la base de datos y vuelva a crearla en el punto. Aquí está mi models.py
:
from django.db import models
from pygments.lexers import get_all_lexers
from pygments.styles import get_all_styles
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight
LEXERS = [item for item in get_all_lexers() if item[1]]
LANGUAGE_CHOICES = sorted([(item[1][0], item[0]) for item in LEXERS])
STYLE_CHOICES = sorted((item, item) for item in get_all_styles())
class Snippet(models.Model):
owner = models.ForeignKey('auth.User', related_name="snippets")
highlighted = models.TextField()
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default="")
code = models.TextField()
linenos = models.BooleanField(default=False)
language = models.CharField(choices=LANGUAGE_CHOICES,
default="python",
max_length=100)
style = models.CharField(choices=STYLE_CHOICES,
default="friendly",
max_length=100)
class Meta:
ordering = ('created',)
def save(self, *args, **kwargs):
"""
Use the 'pygments' library to create a highlighted HTML
representation of the code snippet.
"""
lexer = get_lexer_by_name(self.language)
linenos = self.linenos and 'table' or False
options = self.title and {'title': self.title} or {}
formatter = HtmlFormatter(style=self.style, linenos=linenos,
full=true, **options)
self.highlighted = highlight(self.code, lexer, formatter)
super(Snippet, self).save(*args, **kwargs)
Mi serializers.py
:
from django.forms import widgets
from rest_framework import serializers
from snippets.models import Snippet, LANGUAGE_CHOICES, STYLE_CHOICES
from django.contrib.auth.models import User
class SnippetSerializer(serializers.ModelSerializer):
owner = serializers.Field(source="owner.username")
class Meta:
model = Snippet
fields = ('id', 'title', 'code', 'linenos', 'language', 'style', 'owner')
class UserSerializer(serializers.ModelSerializer):
snippets = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = User
fields = ('id', 'username', 'snippets')
Mi views.py
:
from snippets.models import Snippet
from snippets.serializers import SnippetSerializer
from rest_framework import generics
from django.contrib.auth.models import User
from snippets.serializers import UserSerializer
from rest_framework import permissions
class SnippetList(generics.ListCreateAPIView):
"""
List all snippets, or create a new snippet.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def pre_save(self, obj):
obj.owner = self.request.user
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
"""
Retrieve, update or delete a nippet instance.
"""
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
def pre_save(self, obj):
obj.owner = self.request.user
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class UserList(generics.ListAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
class UserDetail(generics.RetrieveAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
y finalmente mi urls.py
from django.conf.urls import include
from django.conf.urls import patterns, url
from rest_framework.urlpatterns import format_suffix_patterns
from snippets import views
urlpatterns = patterns('',
url(r'^snippets/$', views.SnippetList.as_view()),
url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view()),
url(r'^users/$', views.UserList.as_view()),
url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
)
urlpatterns = format_suffix_patterns(urlpatterns)
urlpatterns += patterns('',
url(r'^api-auth/', include('rest_framework.urls',
namespace="rest_framework")),
)
Me disculpo si publiqué un montón de información innecesaria. Gracias de antemano chicos.
Editar: Esquema DB:
CREATE TABLE "snippets_snippet" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
"created" datetime NOT NULL, "title" varchar(100) NOT NULL, "code" text NOT NULL,
"linenos" bool NOT NULL, "language" varchar(100) NOT NULL, "style" varchar(100) NOT NULL);
Después de investigar un poco, descubrí que al eliminar y volver a crear la base de datos (como dice el tutorial) en lugar de usar el make migrations
comando, no solo NO agregaría las columnas, sino que tampoco me diría que algo estaba mal al ejecutar el make migrations
comando me dice:
You are trying to add a non-nullable field 'highlighted' to snippet 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
Si comento el highlighted
sección en models.py
publicará el mismo mensaje anterior pero para el owner
línea. Así que quiere un valor predeterminado para ambos. highlighted
y owner
, pero no estoy seguro de qué usar. Además, el tutorial tampoco me está ayudando.
burhan khalid
A medida que avanzaba en el tutorial, debe haber encontrado la sección sobre migración, ya que este fue uno de los principales cambios en Django 1.7.
Antes de Django 1.7, el comando syncdb nunca hizo ningún cambio que tuviera la posibilidad de destruir los datos actualmente en la base de datos. Esto significaba que si sincronizaba un modelo y luego agregaba una nueva fila al modelo (una nueva columna, efectivamente), syncdb no afectaría ese cambio en la base de datos.
Entonces, o soltó esa tabla a mano y luego ejecutó syncdb nuevamente (para recrearla desde cero, perdiendo cualquier dato), o ingresó manualmente las declaraciones correctas en la base de datos para agregar solo esa columna.
Entonces surgió un proyecto llamado south
que implementó migraciones. Esto significaba que había una manera de migrar hacia adelante (y revertir, deshacer) cualquier cambio en la base de datos y preservar la integridad de los datos.
En Django 1.7, la funcionalidad de south
se integró directamente en Django. Cuando se trabaja con migraciones, el proceso es un poco diferente.
- Hacer cambios a
models.py
(como normal). - Crear una migración. Esto genera código para pasar del estado actual al siguiente estado de su modelo. Esto se hace con el
makemigrations
dominio. Este comando es lo suficientemente inteligente como para detectar qué ha cambiado y creará una secuencia de comandos para efectuar ese cambio en su base de datos. - A continuación, aplica esa migración con
migrate
. Este comando aplica todas las migraciones en orden.
Así que tu normal syncdb
ahora es un proceso de dos pasos, python manage.py makemigrations
seguido por python manage.py migrate
.
Ahora, a su problema específico:
class Snippet(models.Model):
owner = models.ForeignKey('auth.User', related_name="snippets")
highlighted = models.TextField()
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100, blank=True, default="")
code = models.TextField()
linenos = models.BooleanField(default=False)
language = models.CharField(choices=LANGUAGE_CHOICES,
default="python",
max_length=100)
style = models.CharField(choices=STYLE_CHOICES,
default="friendly",
max_length=100)
En este modelo, tienes dos campos. highlighted
y code
que se requiere (no pueden ser nulos).
Si hubiera agregado estos campos desde el principio, ¿no habría ningún problema porque la tabla no tiene filas existentes?
Sin embargo, si la tabla ya se creó y agrega un campo que no puede ser nulo, debe definir un valor predeterminado para proporcionar filas existentes; de lo contrario, la base de datos no aceptará sus cambios porque violarían las restricciones de integridad de datos. .
Esto es lo que le indica el comando. Puede decirle a Django que aplique un valor predeterminado durante la migración, o puede darle un valor predeterminado “en blanco” highlighted = models.TextField(default="")
en el modelo mismo.
-
Sin embargo, lo que dice tiene sentido, ¿no debería solucionar el problema si elimino la tabla? Dado que estaría recreando la tabla, esos campos estarían allí desde el principio, ¿verdad? Pero en la práctica (al menos cuando lo hago, creo que lo estoy haciendo bien…) sigue sin funcionar, ahora sin embargo, cuando ejecuto el
makemigrations
comando dice que todo está bien y “no se detectaron cambios”, pero cuando entro en el shell y miro el esquema db todavía no muestra elowner
ohighlighted
campos.– Taylor Allred
14 de octubre de 2014 a las 6:38
-
Si eliminó la tabla, debe volver a migrar. Debería haber una carpeta llamada migraciones en su aplicación, vea cuántas migraciones hay.
– Burhan Jalid
14 de octubre de 2014 a las 9:37
-
Sin embargo, el tutorial indica que se debe eliminar el archivo sqlite y ejecutar syncdb para volver a crearlo. Incluso en este caso, el campo no se creó en la tabla snippets_snippet.
– n4cer500
14/10/2014 a las 13:43
-
Así que actualmente mis campos en mi modelo se ven como
owner = models.ForeignKey('auth.User', related_name='snippets')
yhighlighted = models.TextField()
¿Deberían verse comoowner = models.ForeignKey('auth.User', related_name='snippets', default='')
yhighlighted = models.TextField(default='')
?– Taylor Allred
14/10/2014 a las 23:29
-
Ok, hasta ahora, parece estar funcionando, completé los cambios en los campos que tenía en el comentario anterior publicado. En el mínimo, me permite continuar con el tutorial y no me da errores, todavía no estoy 100% seguro de si esto solucionó completamente el problema, pero hasta ahora todo bien. Si me encuentro con más problemas en el camino que coincidan con este problema, publicaré una actualización aquí; de lo contrario, si tengo otro problema que no puedo resolver, publicaré otra pregunta. ¡Gracias por la ayuda a todos!
– Taylor Allred
15 de octubre de 2014 a las 3:52
Paso 1: elimine el archivo db.sqlite3.
Paso 2: $ python manage.py migrar
Paso 3: $ python manage.py makemigrations
Paso 4: Cree el superusuario usando $ python manage.py createsuperuser
el nuevo db.sqlite3 se generará automáticamente
-
me salvaste la vida jaja gracias
– usuario10719814
25 oct 2021 a las 21:11
-
Me salvaste con el paso 1. Esto
db.sqlite3
era la razón de todos mis problemas.– Momento
27 abr a las 13:31
-
tengo que especificar
python manage.py makemigrations snippets
–Shiv Krishna Jaiswal
11 de junio a las 14:48
-
Esto solucionó mi problema jajaja >>> Paso 1: Eliminar el archivo db.sqlite3.
– Shashi123
21 de agosto a las 1:33
-
¿Esta solución está relacionada solo con Sqlite3? ¿Y si estamos en producción con PostgreSQL? En este caso, eliminar toda la base de datos no parece una gran idea.
– usuario840718
13 oct a las 13:13
Centrémonos en el error:
Valor de excepción: no existe tal columna: snippets_snippet.owner_id
A ver si eso es cierto…
Puede usar el comando manage.py para acceda a su shell de base de datos (esto usará las variables settings.py, por lo que seguramente se conectará a la correcta).
manage.py dbshell
Ahora puede mostrar los detalles de su tabla escribiendo:
.schema TABLE_NAME
O en tu caso:
.schema snippets_snippet
Se pueden encontrar más comandos sqlite aquí o emitiendo un:
.help
Por último, termine su sesión escribiendo:
.quit
Esto no lo saca del bosque, pero lo ayuda a saber en qué parte del problema trabajar 🙂
¡Buena suerte!
-
Muchas gracias por mostrarme cómo acceder al shell sqlite (o cualquier shell que esté configurado)… muy impresionante y no sé por qué no aprendí sobre esto antes… ¡Gracias!
– twknab
13 mayo 2017 a las 11:27
copser
Veo que tenemos el mismo problema aquí, tengo el mismo error. Quiero escribir esto para el futuro usuario que experimentará el mismo error. Después de realizar cambios en su modelo de Fragmento de clase como dijo @Burhan Khalid, debe migrar las tablas:
python manage.py makemigrations snippets
python manage.py migrate
Y eso debería resolver el error. Disfrutar.
Este error puede ocurrir si crea una instancia de una clase que se basa en esa tabla, por ejemplo, en views.py.
-
muy útil – Te daría muchos más +1 si pudiera. Estoy practicando con la creación de objetos con modelos Django y había creado instancias de algunas instancias de clase manualmente en
views.py
en lugar de enviar un formulario, etc. Una vez que eliminé estos eventos de creación, pudemakemigrations
ymigrate
sin eldjango.db.utils.OperationalError: table {{project}}_{{app}} has no column named {{field_trying_to_add}}
error. ¡Gracias!– twknab
12 de mayo de 2017 a las 7:12
-
Puedes explicarme mas ?
–Istiaque Ahmed
12 de junio de 2018 a las 5:40
-
@istiaque-ahmed Este error me sucedió cuando estaba instanciando una clase con un modelo en el nivel de toda la aplicación. El mecanismo de migración no pudo verificar los atributos en el tiempo de ejecución y no pudo ejecutar los cambios para el modelo/tabla en particular.
– tuétano
12 de junio de 2018 a las 10:08
Inicialmente, he comentado mis nuevos campos que están causando esos errores y ejecuto python manage.py hacer migraciones y entonces python manage.py migrar para eliminar realmente esos nuevos campos.
class FootballScore(models.Model):
team = models.ForeignKey(Team, related_name="teams_football", on_delete=models.CASCADE)
# match_played = models.IntegerField(default="0")
# lose = models.IntegerField(default="0")
win = models.IntegerField(default="0")
# points = models.IntegerField(default="0")
class FootballScore(models.Model):
team = models.ForeignKey(Team, related_name="teams_football", on_delete=models.CASCADE)
match_played = models.IntegerField(default="0")
lose = models.IntegerField(default="0")
win = models.IntegerField(default="0")
points = models.IntegerField(default="0")
Luego los descomenté y ejecuté python manage.py hacer migraciones y python manage.py migrar y bum. Funcionó para mí. 🙂
-
muy útil – Te daría muchos más +1 si pudiera. Estoy practicando con la creación de objetos con modelos Django y había creado instancias de algunas instancias de clase manualmente en
views.py
en lugar de enviar un formulario, etc. Una vez que eliminé estos eventos de creación, pudemakemigrations
ymigrate
sin eldjango.db.utils.OperationalError: table {{project}}_{{app}} has no column named {{field_trying_to_add}}
error. ¡Gracias!– twknab
12 de mayo de 2017 a las 7:12
-
Puedes explicarme mas ?
–Istiaque Ahmed
12 de junio de 2018 a las 5:40
-
@istiaque-ahmed Este error me sucedió cuando estaba instanciando una clase con un modelo en el nivel de toda la aplicación. El mecanismo de migración no pudo verificar los atributos en el tiempo de ejecución y no pudo ejecutar los cambios para el modelo/tabla en particular.
– tuétano
12 de junio de 2018 a las 10:08
Mayank Khanna
Me enfrenté a este problema y así es como lo resolví.
1) Elimine todos los registros de migración del directorio de migración de su aplicación. Estos son archivos llamados 0001_,0002_,0003_ etc. Tenga cuidado de no borrar el archivo _init__.py.
2) Elimine el archivo db.sqlite3. Será regenerado más tarde.
Ahora, ejecute los siguientes comandos:
python manage.py makemigrations appname
python manage.py migrate
Asegúrese de escribir el nombre de su aplicación después de realizar migraciones. Es posible que deba crear un superusuario para acceder nuevamente a su base de datos. Hazlo de la siguiente manera
python manage.py createsuperuser
-
Gracias por indicar que el nombre de la aplicación también es necesario al realizar migraciones. Esto ayudó
– Amresh Giri
18 de agosto de 2020 a las 18:16
Si eliminó la base de datos y volvió a ejecutar syncdb, no esperaría que tuviera este problema. ¿Está seguro de que eliminó el archivo SQLite db correcto?
– Alasdair
11 de octubre de 2014 a las 9:57
Voté a favor de su pregunta, no por la pregunta en sí, sino por la minuciosidad de los detalles y la franqueza de lo que ha intentado. Las preguntas bien presentadas no son tan comunes. Desafortunadamente estoy en el móvil y no puedo dar una respuesta adecuada. Buena suerte, no obstante. Volveré a consultar más tarde para ver cómo van las cosas.
– skzryzg
11/10/2014 a las 13:46
No sabía que podría estar eliminando la base de datos incorrecta. ejecuto el comando
rm tmp.db
y entoncespython manage.py syncdb
cada vez que lo hago, me pide que cree un superusuario, lo cual hago. Hago esto en la misma pestaña de terminal que he hecho el resto del proyecto mientras también estoy en el mismo entorno.– Taylor Allred
11/10/2014 a las 18:43
Entonces, ¿alguien más tiene una posible solución?
– Taylor Allred
12 de octubre de 2014 a las 5:34
Yo también tuve esto, no pude resolverlo. Clonar el git del tutorial y ejecutar la sincronización parece crear el campo id_propietario en sqllite, pero no pude hacer que lo hiciera siguiendo el tutorial.
– n4cer500
13/10/2014 a las 22:04