【发布时间】:2022-05-13 09:47:02
【问题描述】:
我想在 heroku 中更新我的数据库表。但是,当我使用 heroku pg:info DATABASE 检查表的状态时,我意识到没有创建表,但它们是在 models.py 中定义的,如问题底部所示。
=== DATABASE_URL
Plan: Hobby-dev
Status: Available
Connections: 0/20
PG Version: 12.4
Created: 2020-10-13 23:10 UTC
Data Size: 8.2 MB
Tables: 0 # <---------------------------no tables
Rows: 0/10000 (In compliance)
Fork/Follow: Unsupported
Rollback: Unsupported
Continuous Protection: Off
Add-on: postgresql-closed-00235
这就是我的 Python Flask 应用程序的设置方式:
config.py
import os
basedir = os.path.abspath(os.path.dirname(__file__))
class Config(object):
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL') or \
'sqlite:///' + os.path.join(basedir, 'app.db')
SQLALCHEMY_TRACK_MODIFICATIONS = False
MAIL_SERVER='smtp.gmail.com'
MAIL_PORT=587
MAIL_USE_TLS=1
MAIL_USERNAME='my-username'
MAIL_PASSWORD='my-password'
ADMINS=['admin-email']
POSTS_PER_PAGE=10
STRIPE_PUBLISHABLE_KEY='<stripe-publishable-key>'
STRIPE_SECRET_KEY='<stripe-secret-key>'
STRIPE_ENDPOINT_SECRET='<stripe-endpoint-secret>'
LOG_TO_STDOUT = os.environ.get('LOG_TO_STDOUT')
__init__.py
from flask import Flask
from config import Config
from flask_bootstrap import Bootstrap
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
import logging
from logging.handlers import SMTPHandler, RotatingFileHandler
import os
from flask_mail import Mail
from flask_moment import Moment
import stripe
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db)
login = LoginManager(app)
login.login_view = 'login'
bootstrap = Bootstrap(app)
mail = Mail(app)
moment = Moment(app)
stripe_keys = {
'secret_key': app.config['STRIPE_SECRET_KEY'],
'publishable_key': app.config['STRIPE_PUBLISHABLE_KEY'],
'endpoint_secret': app.config['STRIPE_ENDPOINT_SECRET']
}
stripe.api_key = stripe_keys['secret_key']
if not app.debug:
if app.config['MAIL_SERVER']:
auth = None
if app.config['MAIL_USERNAME'] or app.config['MAIL_PASSWORD']:
auth = (app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])
secure = None
if app.config['MAIL_USE_TLS']:
secure = ()
mailhandler = SMTPHandler(
mailhost=(app.config['MAIL_SERVER'], app.config['MAIL_PORT']),
fromaddr='noreply@' + app.config['MAIL_SERVER'],
toaddrs=app.config['ADMINS'],
subject='Somasoma: Error',
credentials=auth, secure=secure
)
mailhandler.setLevel(logging.ERROR)
app.logger.addHandler(mailhandler)
if app.config['LOG_TO_STDOUT']:
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
app.logger.addHandler(stream_handler)
else:
if not os.path.exists('logs'):
os.mkdir('logs')
file_handler = RotatingFileHandler('logs/somasoma.log', maxBytes=10240, backupCount=10)
file_handler.setFormatter(logging.Formatter(
'%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d] '
))
file_handler.setLevel(logging.INFO)
app.logger.addHandler(file_handler)
app.logger.setLevel(logging.INFO)
app.logger.info('Somasoma Blog')
from app import routes, models, errors
blog_app.py
from app import app, db
from app.models import User, Post
@app.shell_context_processor
def make_shell_context():
return {'db':db, 'User': User, 'Post': Post}
Procfile
web: flask db upgrade; gunicorn blog_app:app
理想情况下,为了更新我的数据库,我已经运行了heroku run flask db upgrade 命令。这反而引发了我这个错误:
sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateTable) relation "user" already exists
[SQL:
CREATE TABLE "user" (
id SERIAL NOT NULL,
username VARCHAR(64),
email VARCHAR(120),
password_hash VARCHAR(128),
about_me VARCHAR(140),
last_seen TIMESTAMP WITHOUT TIME ZONE,
PRIMARY KEY (id)
)
问题是当我尝试在 heroku 上登录 my deployed up 时,由于 stdout heroku 日志中不存在“用户”,我无法注册或登录:
psycopg2.errors.UndefinedTable: relation "user" does not exist
2020-10-13T23:27:13.018103+00:00 app[web.1]: LINE 2: FROM "user"
SQL: SELECT "user".id AS user_id, "user".username AS user_username, "user".email AS user_email, "user".password_hash AS user_password_hash
2020-10-13T23:27:13.018113+00:00 app[web.1]: FROM "user"
2020-10-13T23:27:13.018114+00:00 app[web.1]: WHERE "user".username = %(username_1)s
2020-10-13T23:27:13.018114+00:00 app[web.1]: LIMIT %(param_1)s]
2020-10-13T23:27:13.018114+00:00 app[web.1]: [parameters: {'username_1': 'harry', 'param_1': 1}]
2020-10-13T23:27:13.018114+00:00 app[web.1]: (Background on this error at: http://sqlalche.me/e/f405)
此错误是数据库表为空的直接结果。我查看了几个示例解决方案,例如 this 和 this,但我不太能够解决我面临的数据库问题。
就个人而言,我认为在 __init__.py 中实例化 migrate 变量时包含参数 db 可以解决这个问题。我的意思是:
代替:
migrate = Migrate(app)
那么这应该可以解决它:
migrate = Migrate(app, db)
但是,有了这个附加功能,我仍然无法修复这个错误。
我会错过什么?非常感谢任何线索或方向。
已编辑:
我为我的数据库定义了一个用户和帖子模型:
models.py
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key = True)
username = db.Column(db.String(64), index = True, unique = True)
email = db.Column(db.String(120), index = True, unique = True)
password_hash = db.Column(db.String(128))
posts = db.relationship('Post', backref = 'author', lazy = 'dynamic')
def __repr__(self):
return '<User {}>'.format(self.username)
class Post(db.Model):
id = db.Column(db.Integer, primary_key = True)
body = db.Column(db.String(140))
timestamp = db.Column(db.DateTime, index = True, default = datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return 'Post <>'.format(self.body)
@login.user_loader
def load_user(id):
return User.query.get(int(id))
【问题讨论】:
标签: python postgresql flask heroku sqlalchemy