【问题标题】:I delete database on heroku but also this error: sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) table thesis_have_keywords already exists我在heroku上删除了数据库,但也出现了这个错误:sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) table thesis_have_keywords already exists
【发布时间】:2020-02-23 03:40:47
【问题描述】:

我在 heroku 上部署了这段代码,我正在使用 CI/CD 与 travis 和 heroku。出于开发原因,我正在使用 SQLite 数据库。我希望每次在 heroku 上部署 repo 时,数据库将被删除并使用文件数据再次创建。我这样做了,但是 heroku 给了我标题错误。

这是我的代码:

初始化.py:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_admin import Admin
import os

db = SQLAlchemy()

def create_app(conf_test=None):
    app = Flask(__name__, instance_relative_config=True)

    print("instance path --- " + os.path.join(app.instance_path, 'database.db'))
    app.config.from_mapping(
        SQLALCHEMY_DATABASE_URI = ''.join(['sqlite:////', os.path.join(app.instance_path, 'database.db')]),
        SQLALCHEMY_TRACK_MODIFICATIONS = os.environ['SQLALCHEMY_TRACK_MODIFICATIONS'],
        JWT_KEY = os.environ['JWT_KEY'],
        SECRET_KEY = os.environ['SECRET_KEY']
    )

    if conf_test is not None:
        app.config.update(conf_test)

    from .model import init_db
    with app.app_context(): init_db()

    from .views import init_views
    with app.app_context(): init_views()

    @app.route("/")
    def hello():
        return "it's working..." 

    return app

模型.py

class CurrentState(enum.Enum):
    available = 'AVAILABLE'
    in_progress = 'IN PROGRESS'
    finished = 'FINISHED'

thesis_have_keywords = db.Table('thesis_have_keywords', 
    db.Column('thesis_id', db.Integer, db.ForeignKey("thesis.id")),
    db.Column('keyword_id', db.Integer, db.ForeignKey("keyword.id"))
)

thesis_have_teaching = db.Table('thesis_have_teaching', 
    db.Column('thesis_id', db.Integer, db.ForeignKey("thesis.id")),
    db.Column('teaching_id', db.Integer, db.ForeignKey("teaching.id"))
)

thesis_have_courses = db.Table('thesis_have_courses', 
    db.Column('thesis_id', db.Integer, db.ForeignKey("thesis.id")),
    db.Column('course_id', db.Integer, db.ForeignKey("degree_courses.id"))
)

class Teacher(db.Model):
    name = db.Column(db.String(50), unique=False, nullable=False)
    surname = db.Column(db.String(50), unique=False, nullable=False)
    mail = db.Column(db.String(100), unique=True, nullable=False)
    id = db.Column(db.String(100), unique=True, nullable=False, primary_key=True)

    thesis = db.relationship("Thesis", back_populates="teacher")


class Thesis(db.Model):
    title = db.Column(db.String(150), unique=True, nullable=False)
    description = db.Column(db.Text, unique=False, nullable=False)
    last_modify = db.Column(db.DateTime(timezone=True), unique=False, nullable=False, default=datetime.datetime.utcnow)
    duration = db.Column(db.Integer, unique=False, nullable=True)
    start_time = db.Column(db.DateTime(timezone=True), unique=False, nullable=True)
    end_time = db.Column(db.DateTime(timezone=True), unique=False, nullable=True)
    current_state = db.Column(db.Enum(CurrentState), unique=False, nullable=False, default=CurrentState('AVAILABLE'))
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)

    teacher_id = db.Column(db.Integer, db.ForeignKey("teacher.id"))
    teacher = db.relationship("Teacher", back_populates="thesis")

    keywords = db.relationship("Keyword", back_populates="thesis", secondary=thesis_have_keywords)

    teaching = db.relationship("Teaching", back_populates="thesis", secondary=thesis_have_teaching)

    courses = db.relationship("DegreeCourses", back_populates="thesis", secondary=thesis_have_courses)

class Keyword(db.Model):
    name = db.Column(db.String(50), unique=True, nullable=False)
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)

    thesis = db.relationship("Thesis", back_populates="keywords", secondary=thesis_have_keywords)

class Teaching(db.Model):
    name = db.Column(db.String(50), unique=False, nullable=False)
    code = db.Column(db.String(100), unique=True, nullable=False)
    id = db.Column(db.Integer, autoincrement=True, primary_key=True) 

    thesis = db.relationship("Thesis", back_populates="teaching", secondary=thesis_have_teaching)

class DegreeCourses(db.Model):
    name = db.Column(db.String(50), unique=False, nullable=False)
    code = db.Column(db.String(100), unique=True, nullable=False)
    _type = db.Column(db.String(20), unique=False, nullable=False)
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)

    thesis = db.relationship("Thesis", back_populates="courses", secondary=thesis_have_courses)

def init_db():
    with current_app.app_context():
        if os.path.exists(current_app.instance_path):
            shutil.rmtree(current_app.instance_path)

        try:
            os.makedirs(current_app.instance_path)
        except OSError:
            pass

        db.init_app(current_app)
        db.drop_all()
        db.session.commit()        
        db.create_all()

        with open("server/teachers.json") as teach_file:
            data = json.load(teach_file)

        teacher_entries=[]
        for teacher in data['teachers']:
            teach = Teacher(name=teacher['name'], surname=teacher['surname'], mail=teacher['mail'], id=teacher['id'])
            teacher_entries.append(teach)

        db.session.add_all(teacher_entries)
        db.session.commit()

每次我删除实例文件夹并重新创建它时。我也尝试只删除数据库文件,但出现同样的错误。

sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) table thesis_have_keywords 已经存在

【问题讨论】:

  • “每次我删除实例文件夹”是什么意思? SQLite 和 Heroku 不能很好地结合在一起,但也可能存在其他问题。
  • 对不起我的英语,我的意思是每次我部署一个存储库时,我都会删除所有实例存储库,然后我重新创建它。我知道 sqlite 不是最佳选择,但由于外部原因,我必须使用它。仅出于开发原因。但是每次部署时,heroku 都会给我这个错误。
  • 有充分的理由不在 Heroku 上使用 SQLite。您的数据会经常丢失(不仅仅是在部署时)。但是我仍然不确定“我删除所有实例存储库然后我重新创建它”是什么意思。你在运行什么命令?在哪里?
  • 我猜这个代码。 if os.path.exists(current_app.instance_path): shutil.rmtree(current_app.instance_path)。抱歉,我的意思是我每次部署代码时都会删除实例文件夹。我也尝试只删除 database.db 文件,但我也遇到了同样的问题。
  • 你不应该手动删除任何东西,你尤其是不应该在这样的应用程序代码中这样做。当您部署到 Heroku 时,您每次都会获得一个全新的环境(尽管使用一些构建包,您可能能够缓存库)。

标签: python-3.x sqlite heroku flask flask-sqlalchemy


【解决方案1】:

您将来可能会遇到其他问题(有很好的理由不在 Heroku 上使用 SQLite),但如果您的 database.db 未被跟踪,则不应出现该特定错误。

试试这个:

git rm --cached database.db
git commit -m 'Untrack database'
git push heroku master

请注意,每当您的 dyno 重新启动时,您的数据库都会丢失,happens frequently(至少每天一次,以及每当您部署或更改环境变量或附加组件时)。

【讨论】:

    猜你喜欢
    • 2019-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 2021-10-19
    • 2020-12-01
    • 2021-01-12
    • 2021-07-24
    相关资源
    最近更新 更多