Flask SQL no such table - python

I've tried this before and it worked, now I'm doing it again but it doesn't. I use a virtual env.
The db file is in the same directory as the init and models. I've also executed the db.create_all() in the python shell after importing db. The error occurs when I execute Students.query.all(). I'm really confused now. I compared my codes with my existing projects and it is the same. I don't understand why it doesn't work.
Traceback (most recent call last):
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1246, in _execute_context
cursor, statement, parameters, context
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\default.py", line 581, in do_execute
cursor.execute(statement, parameters)
sqlite3.OperationalError: no such table: students
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\orm\query.py", line 3211, in all
return list(self)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\orm\query.py", line 3367, in __iter__
return self._execute_and_instances(context)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\orm\query.py", line 3392, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 982, in execute
return meth(self, multiparams, params)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\sql\elements.py", line 287, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1101, in _execute_clauseelement
distilled_params,
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1250, in _execute_context
e, statement, parameters, cursor, context
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1476, in _handle_dbapi_exception
util.raise_from_cause(sqlalchemy_exception, exc_info)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\util\compat.py", line 398, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\util\compat.py", line 152, in reraise
raise value.with_traceback(tb)
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1246, in _execute_context
cursor, statement, parameters, context
File "C:\Users\Martin\Desktop\regtry\venv\lib\site-packages\sqlalchemy\engine\default.py", line 581, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: students
[SQL: SELECT students.id AS students_id, students.last_name AS students_last_name, students.college AS students_college, students.email AS students_email
FROM students]
(Background on this error at: http://sqlalche.me/e/e3q8)
_ _ init _ _.py:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
main = Flask(__name__)
main.config['SECRET_KEY'] = '3bce79429ad6b79670e4e800fb4a57b9'
main.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(main)
from reg import routes
models.py:
from reg import db
class Students(db.Model):
id = db.Column(db.Integer, primary_key=True)
last_name = db.Column(db.String(60), nullable=False)
college = db.Column(db.String(60), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"Student('{self.last_name}','{self.college}','{self.email}')"

It probably has to do with where you are calling db.create_all(). You have to call it after you have defined all of your models. Here is a working example in one module:
import flask
from flask_sqlalchemy import SQLAlchemy
app = flask.Flask(__name__)
app.config['SECRET_KEY'] = '3bce79429ad6b79670e4e800fb4a57b9'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(app)
class Students(db.Model):
id = db.Column(db.Integer, primary_key=True)
last_name = db.Column(db.String(60), nullable=False)
college = db.Column(db.String(60), nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
def __repr__(self):
return f"Student('{self.last_name}','{self.college}','{self.email}')"
db.create_all()
#app.route("/students", methods=["GET"])
def all_students():
students = Students.query.all()
resp = []
for student in students:
resp.append(dict(
id=student.id,
last_name=student.last_name,
college=student.college,
email=student.email
))
return flask.jsonify(resp), 200
#app.route("/students/<_id>", methods=["GET"])
def student_by_id(_id):
student = Students.query.get(_id)
if student:
resp = dict(
id=student.id,
last_name=student.last_name,
college=student.college,
email=student.email
)
return flask.jsonify(resp), 200
else:
return "", 404
#app.route("/students", methods=["POST"])
def add_student():
req = flask.request.get_json()
student = Students(**req)
db.session.add(student)
db.session.commit()
resp = flask.make_response()
resp.headers["Location"] = flask.url_for("student_by_id", _id=student.id)
return resp, 201
In your example I did not see a call to db.create_all() but I suspect that it is in the wrong spot. Using your example, I believe it will work if you move the call from where you have it to the end of your __init__.py:
__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
main = Flask(__name__)
main.config['SECRET_KEY'] = '3bce79429ad6b79670e4e800fb4a57b9'
main.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db = SQLAlchemy(main)
from reg import routes
db.create_all()

In the shell, import the database and the models first before executing db.create_all(). Apparently, error occurs when create you create database without importing the models.
My mistake was:
>>from APPFOLDER import db
>>db.create_all()
>>from APPFOLDER.models import MODELNAME
>>MODELNAME.query.all()
***ERROR MSG***
What you should do:
>>from APPFOLDER import db
>>from APPFOLDER.models import MODELNAME
>>db.create_all()
>>MODELNAME.query.all()
[]

Related

ModuleNotFoundError: No module named '_sqlite3' (SQLAlchemy Flask)

I have used sql-alchemy for so long but I don't know it suddnly stopped working and showing me errors
Code
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# create the extension
db = SQLAlchemy()
# create the app
app = Flask(__name__)
# configure the SQLite database, relative to the app instance folder
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
# initialize the app with the extension
db.init_app(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String, unique=True, nullable=False)
email = db.Column(db.String)
with app.app_context():
db.create_all()
this is code available on sqlalchemy documentation
Error
(venv) viral#viral-Lenovo:~/Desktop/sql-practice$ python main.py
Traceback (most recent call last):
File "/home/viral/Desktop/sql-practice/main.py", line 11, in <module>
db.init_app(app)
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/flask_sqlalchemy/extension.py", line 326, in init_app
engines[key] = self._make_engine(key, options, app)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/flask_sqlalchemy/extension.py", line 614, in _make_engine
return sa.engine_from_config(options, prefix="")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/sqlalchemy/engine/create.py", line 817, in engine_from_config
return create_engine(url, **options)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<string>", line 2, in create_engine
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/sqlalchemy/util/deprecations.py", line 277, in warned
return fn(*args, **kwargs) # type: ignore[no-any-return]
^^^^^^^^^^^^^^^^^^^
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/sqlalchemy/engine/create.py", line 605, in create_engine
dbapi = dbapi_meth(**dbapi_args)
^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/viral/Desktop/sql-practice/venv/lib/python3.11/site-packages/sqlalchemy/dialects/sqlite/pysqlite.py", line 504, in import_dbapi
from sqlite3 import dbapi2 as sqlite
File "/usr/local/lib/python3.11/sqlite3/__init__.py", line 57, in <module>
from sqlite3.dbapi2 import *
File "/usr/local/lib/python3.11/sqlite3/dbapi2.py", line 27, in <module>
from _sqlite3 import *
ModuleNotFoundError: No module named '_sqlite3'
I expected that it will create a database by creating new folder called instance. but it's only creating instance folder but not database
I have tried creating new venv, reinstalling python and restarting pc but still it's showing the same error.
note: I am using Linux, Ubuntu Kde plasma

How to fix incorrect SQLAlchemy metadata after migration

I have defined and created a SQLite database using SQLAlchemy, and added some data. This database has been working fine. However, I made a change to a column name in one the models ("User") and migrated this change using alembic. The current model looks like this, where the old name "analogy" was changed to "metaphor":
class User(Base):
__tablename__ = "user"
id = Column(Integer, primary_key=True)
username = Column(String(32), nullable=False, index=True, unique=True)
registered_on = Column(DateTime, index=True, default=datetime.now())
metaphor = Column(String(16))
The migration seemed to go fine, and I also doublechecked using the SQLite command line to confirm that the schema actually changed.
sqlite > .schema
CREATE TABLE "user" (
id INTEGER NOT NULL,
username VARCHAR(32) NOT NULL,
registered_on DATETIME,
metaphor VARCHAR(16),
PRIMARY KEY (id),
UNIQUE (wc_id)
);
CREATE UNIQUE INDEX ix_user_username ON user (username);
CREATE INDEX ix_user_registered_on ON user (registered_on);
But now when I try to query the table in Python, I get the following error, referencing the old column name and saying that there is no such column
>>> from background.database import db_session
>>> from data.models import User
>>> users = db_session.query(User).all()
Traceback (most recent call last):
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
context)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/engine/default.py", line 509, in do_execute
cursor.execute(statement, parameters)
sqlite3.OperationalError: no such column: user.analogy
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 2843, in all
return list(self)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 2995, in __iter__
return self._execute_and_instances(context)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 3018, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 948, in execute
return meth(self, multiparams, params)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/sql/elements.py", line 269, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1060, in _execute_clauseelement
compiled_sql, distilled_params
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1200, in _execute_context
context)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1413, in _handle_dbapi_exception
exc_info
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 265, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 248, in reraise
raise value.with_traceback(tb)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/engine/base.py", line 1193, in _execute_context
context)
File "/export/scratch/pt/power/lib/python3.5/site-packages/sqlalchemy/engine/default.py", line 509, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such column: user.goal_period [SQL: 'SELECT user.id AS user_id, user.username AS user_username, user.registered_on AS user_registered_on, user.analogy AS user_analogy \nFROM user'] (Background on this error at: http://sqlalche.me/e/e3q8)
After tracing this error, it looks like the name change to the model is not reflected in the metadata imported from SQLAlchemy. So, SQLAlchemy is still using the metadata from the prior version of the table, while the actual database schema and the defined model have a different column name.
I've tried to delete all caches (.pyc, py_cache) to see if that was the source of the problem.
However, after doing this, there were still no changes to the metadata.
when I open a new interprer session and query the metadata, it shows the old schema, not the new one.
>>> from SQLAlchemy import MetaData
>>> metadata= MetaData()
>>> metadata.tables['user']
Table('user', MetaData(bind=None), Column('id', Integer(), table=<user>, primary_key=True, nullable=False), Column('username', String(length=32), table=<user>, nullable=False), Column('registered_on', DateTime(), table=<user>, default=ColumnDefault(datetime.datetime(2019, 6, 5, 12, 33, 57, 11763))), Column('goal_period', String(length=16), table=<user>, default=ColumnDefault('daily'))), schema=None)
Why is the metadata is not updated, and how do fix this problem?

can't render element of type <class 'sqlalchemy.dialects.postgresql.base.UUID'>

I saw this snippet of code from Flask-common at line 57:
id = db.Column(UUID, default=lambda: str(uuid.uuid4()), primary_key=True)
So I thought I give it a try and use it in my app's models.py (because I prefer to have uuid type for my id's)
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from sqlalchemy.dialects.postgresql import UUID
import uuid
from app import db
class CostCenter(db.Model):
__tablename__ = "costcenter"
id = db.Column('id', UUID(as_uuid=True), default=lambda: str(uuid.uuid4()), primary_key=True)
name = db.Column('name', db.Text)
def __init__(self, name):
self.name = name
def __repr__(self):
return '<id {}>'.format(self.id)
But when I try to run python manage.py db upgrade, it results to an error:
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/compiler.py", line 190, in __init__
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/compiler.py", line 213, in process
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/visitors.py", line 81, in _compiler_dispatch
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/compiler.py", line 2164, in visit_create_table
File "build/bdist.linux-x86_64/egg/sqlalchemy/util/compat.py", line 199, in raise_from_cause
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/compiler.py", line 2153, in visit_create_table
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/compiler.py", line 213, in process
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/visitors.py", line 81, in _compiler_dispatch
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/compiler.py", line 2184, in visit_create_column
File "build/bdist.linux-x86_64/egg/sqlalchemy/dialects/sqlite/base.py", line 847, in get_column_specification
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/compiler.py", line 261, in process
File "build/bdist.linux-x86_64/egg/sqlalchemy/sql/visitors.py", line 79, in _compiler_dispatch
sqlalchemy.exc.CompileError: (in table 'costcenter', column 'id'): Compiler <sqlalchemy.dialects.sqlite.base.SQLiteTypeCompiler object at 0x7fc16
c1f1a50> can't render element of type <class 'sqlalchemy.dialects.postgresql.base.UUID'>
Why can't it render the type UUID? It is recognized in SQLAlchemy but how come it can't in Flask-SQLAlchemy?
Your column definition is using a function that only works with postgresql, and your database type is sqlite.
You need this:
id = db.Column(
'id',
db.Text(length=36),
default=lambda: str(uuid.uuid4()),
primary_key=True)
You can use UUID just in case of using postgresql database.

peewee foreign key error

I am trying to create a simple model for my existing database with peewee.
The database that I'm working on is described in this paper.
I've generated a model with pwiz which works fine, however it didn't create foreign keys for me which enable joining. Therefore I edited the Model so it looks like this:
from peewee import *
database = MySQLDatabase('enron', **{'password': '...', 'user': 'root'})
class UnknownField(object):
pass
class BaseModel(Model):
class Meta:
database = database
class Employee(BaseModel):
email = CharField(db_column='Email_id', unique=True)
eid = PrimaryKeyField()
class Meta:
db_table = 'employeelist'
class Message(BaseModel):
mid = PrimaryKeyField()
sender = ForeignKeyField(Employee,
related_name='messages',
to_field='email') # was CharField() before my edit
class Meta:
db_table = 'message'
However when I try to run:
for message in Message.select():
print message.mid
I get an error:
Traceback (most recent call last):
File "DBModelEnron.py", line 62, in <module>
for message in Message.select():
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2514, in __iter__
return iter(self.execute())
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2507, in execute
self._qr = ResultWrapper(model_class, self._execute(), query_meta)
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2203, in _execute
return self.database.execute_sql(sql, params, self.require_commit)
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2833, in execute_sql
self.commit()
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2688, in __exit__
reraise(new_type, new_type(*exc_value.args), traceback)
File "/usr/local/lib/python2.7/dist-packages/peewee.py", line 2825, in execute_sql
cursor.execute(sql, params or ())
File "/usr/lib/python2.7/dist-packages/MySQLdb/cursors.py", line 174, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/python2.7/dist-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
raise errorclass, errorvalue
peewee.OperationalError: (1054, "Unknown column 't1.sender_id' in 'field list'")
I found a similar problem here, however I have a proper PrimaryKey defined.
Just add a db_column='' to your foreign keys:
sender = ForeignKeyField(Employee,
db_column='sender', # Added this.
related_name='messages',
to_field='email') # was CharField() before my edit

alembic migration error flask

I am making a test blog using the guide found here. It's pretty comprehensive. However, I'm having trouble with the alembic migrations. I can erase all the versions, and spin up a new database with all of the columns just fine. But, when I add a new column I have problems. Here is the code in my models.py:
models.py
....
class Person(db.Model):
__tablename__ = 'person'
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), unique=True)
pwdhash = db.Column(db.String(100))
name = db.Column(db.String(100), unique=True)
def __init__(self, email, name, password):
self.email = email
self.name = name.title()
self.set_password(password)
def __repr__(self):
return '<User %r>' % (self.name)
def set_password(self, password):
self.pwdhash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.pwdhash, password)
#classmethod
def all(cls):
return Person.query.all()
class Category(db.Model):
__tablename__ = 'category'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), unique=True)
description = db.Column(db.Text)
def __unicode__(self):
return self.name
class Article(db.Model):
__tablename__ = 'articles'
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100))
body = db.Column(db.Text)
created = db.Column(db.DateTime, default=datetime.datetime.now)
category_name = db.Column(db.String(10), db.ForeignKey(Category.name))
category = db.relationship(Category)
person_name = db.Column(db.String(100), db.ForeignKey(Person.name, onupdate="CASCADE", ondelete="CASCADE"))
person = db.relationship(Person)
#property
def slug(self):
return urlify(self.title)
#classmethod
def all(cls):
return Article.query.order_by(desc(Article.created)).all()
#classmethod
def find_by_category(cls, category):
return Article.query.filter(Article.category_name == category).all()
It's all pretty standard. However, if I was to add a random column to my People table, like this:
class Person(db.Model):
....
random_column = db.Column(db.Integer())
then run a python manage.py db migrate (which works fine) then run a python manage.py db upgrade then I get the following error:
Traceback (most recent call last):
File "manage.py", line 7, in <module>
manager.run()
File "/Library/Python/2.7/site-packages/flask_script/__init__.py", line 397, in run
result = self.handle(sys.argv[0], sys.argv[1:])
File "/Library/Python/2.7/site-packages/flask_script/__init__.py", line 376, in handle
return handle(app, *positional_args, **kwargs)
File "/Library/Python/2.7/site-packages/flask_script/commands.py", line 145, in handle
return self.run(*args, **kwargs)
File "/Library/Python/2.7/site-packages/flask_migrate/__init__.py", line 82, in upgrade
command.upgrade(config, revision, sql = sql, tag = tag)
File "/Library/Python/2.7/site-packages/alembic/command.py", line 124, in upgrade
script.run_env()
File "/Library/Python/2.7/site-packages/alembic/script.py", line 199, in run_env
util.load_python_file(self.dir, 'env.py')
File "/Library/Python/2.7/site-packages/alembic/util.py", line 198, in load_python_file
module = load_module(module_id, path)
File "/Library/Python/2.7/site-packages/alembic/compat.py", line 55, in load_module
mod = imp.load_source(module_id, path, fp)
File "migrations/env.py", line 72, in <module>
run_migrations_online()
File "migrations/env.py", line 65, in run_migrations_online
context.run_migrations()
File "<string>", line 7, in run_migrations
File "/Library/Python/2.7/site-packages/alembic/environment.py", line 652, in run_migrations
self.get_context().run_migrations(**kw)
File "/Library/Python/2.7/site-packages/alembic/migration.py", line 225, in run_migrations
change(**kw)
File "migrations/versions/4171a9f6ed2a_.py", line 19, in upgrade
op.drop_index('category_name_key', 'category')
File "<string>", line 7, in drop_index
File "<string>", line 1, in <lambda>
File "/Library/Python/2.7/site-packages/alembic/util.py", line 293, in go
return fn(*arg, **kw)
File "/Library/Python/2.7/site-packages/alembic/operations.py", line 716, in drop_index
self._index(name, table_name, ['x'], schema=schema)
File "/Library/Python/2.7/site-packages/alembic/ddl/impl.py", line 164, in drop_index
self._exec(schema.DropIndex(index))
File "/Library/Python/2.7/site-packages/alembic/ddl/impl.py", line 76, in _exec
conn.execute(construct, *multiparams, **params)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 662, in execute
params)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 720, in _execute_ddl
compiled
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 874, in _execute_context
context)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 1024, in _handle_dbapi_exception
exc_info
File "/Library/Python/2.7/site-packages/sqlalchemy/util/compat.py", line 196, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/base.py", line 867, in _execute_context
context)
File "/Library/Python/2.7/site-packages/sqlalchemy/engine/default.py", line 324, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.InternalError: (InternalError) cannot drop index category_name_key because constraint category_name_key on table category requires it
HINT: You can drop constraint category_name_key on table category instead.
'\nDROP INDEX category_name_key' {}
It doesn't even mention the name of the column I created in the stacktrace, so that leads me to believe that something is wrong with the other tables. It mentions the dropping of an index, but I'm not doing anything like that in the migration, just adding a column to the People table. Is it something in alembic that I don't understand?
Like I said it works perfectly find when I spin up a brand new database and load in the configuration. It's only when I make a change and try to migrate that alembic throws me these errors. Does anyone have any idea why this is happening?
EDIT
Just in case people need to see my config.py file:
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
#-----Config the app
SECRET_KEY = 'my_key'
CSRF_ENABLED = True
#-----Config Database
SQLALCHEMY_DATABASE_URI = 'postgresql://username:changeme#localhost/test'
SQLALCHEMY_COMMIT_ON_TEARDOWN = True
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
#-----Config Upload folder
UPLOAD_FOLDER = os.path.realpath('./snb/static') + '/uploads'
I followed the link to the doc on Flask-Migrate to see how it's using alembic, and it says:
The migrate command adds a new migration script. You should review it
and edit it to be accurate, as Alembic cannot detect all changes that
you make to your models. In particular it does not detect indexes, so
those need to be added manually to the script.
Flask-Migrate uses a feature of alembic called "autogenerate", where it tries to compare the state of your database with your models and automatically create a diff.
We use Alembic directly, and I found autogenerate really convenient, but I have to edit it by hand a lot, especially when you're dealing with indexes and constraints.
So my solution would be to do what it says and edit the migration file by hand and remove the lines you don't want or are spurious.

Categories

Resources