【问题标题】:SQLAlchemy inheritance not workingSQLAlchemy 继承不起作用
【发布时间】:2015-03-04 22:08:03
【问题描述】:

我正在使用 Flask 和 SQLAlchemy。我使用了自己的抽象基类和继承。当我尝试在 python shell 中使用我的模型时,出现以下错误:

>>> from schedule.models import Task
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/teelf/projects/schedule/server/schedule/models.py", line 14, in <module>
    class User(Base):
  File "/home/teelf/projects/schedule/server/venv/lib/python3.4/site-packages/flask_sqlalchemy/__init__.py", line 536, in __init__
    DeclarativeMeta.__init__(self, name, bases, d)
  File "/home/teelf/projects/schedule/server/venv/lib/python3.4/site-packages/sqlalchemy/ext/declarative/api.py", line 55, in __init__
    _as_declarative(cls, classname, cls.__dict__)
  File "/home/teelf/projects/schedule/server/venv/lib/python3.4/site-packages/sqlalchemy/ext/declarative/base.py", line 254, in _as_declarative
    **table_kw)
  File "/home/teelf/projects/schedule/server/venv/lib/python3.4/site-packages/sqlalchemy/sql/schema.py", line 393, in __new__
    "existing Table object." % key)
sqlalchemy.exc.InvalidRequestError: Table 'user' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns
 on an existing Table object.

我该如何解决这个问题?

代码:

ma​​nage.py

#!/usr/bin/env python

import os, sys

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

from flask.ext.migrate import Migrate, MigrateCommand
from flask.ext.script import Manager

from server import create_app
from database import db


app = create_app("config")

migrate = Migrate(app, db)
manager = Manager(app)

manager.add_command("db", MigrateCommand)

if __name__ == "__main__":
    manager.run()

__init__.py

from flask import Flask

from flask.ext.login import LoginManager

from database import db
from api import api
from server.schedule.controllers import mod_schedule


def create_app(config):
    # initialize Flask
    app = Flask(__name__)

    # load configuration file
    app.config.from_object(config)

    # initialize database
    db.init_app(app)

    api.init_app(app)

    # initialize flask-login
    login_manager = LoginManager(app)

    # register blueprints
    app.register_blueprint(mod_schedule)

    return app

database.py

from flask.ext.sqlalchemy import SQLAlchemy


db = SQLAlchemy()

models.py

from sqlalchemy.dialects.postgresql import UUID

from database import db


class Base(db.Model):
    __abstract__ = True

    id = db.Column(UUID, primary_key=True)


class User(Base):
    __tablename__ = "user"

    username = db.Column(db.String)
    password = db.Column(db.String)
    first_name = db.Column(db.String)
    last_name = db.Column(db.String)
    authenticated = db.Column(db.Boolean, default=False)

    def __init__(self, first_name, last_name, username):
        self.first_name = first_name
        self.last_name = last_name
        self.username = username

    def is_active(self):
        """ All users are active """
        return True

    def get_id(self):
        return self.username

    def is_authenticated(self):
        return self.authenticated

    def is_anonymous(self):
        """ Anonymous users are not supported"""
        return False

controllers.py

from flask import Blueprint

from flask.ext.restful import reqparse, Resource

from api import api
from server.schedule.models import User


mod_schedule = Blueprint("schedule",  __name__, url_prefix="/schedule")


class Task(Resource):
    def put(self):
        pass

    def get(self):
        pass

    def delete(self):
        pass


api.add_resource(Task, "/tasks/<int:id>", endpoint="task")

【问题讨论】:

  • 两件事可能会有所帮助(虽然我没有机会测试它们):a)在初始化SQLAlchemy()时使用你的Flask应用程序(例如db = SQLAlchemy(app); b)usersreserved key word in PostgreSQL,所以__tablename__ = "users" 可能最终会发生冲突。
  • @cuducos a) 我在__init__.py 中有db.init_app(app)。 b) 我的代码中的表名是user 而不是users
  • @teelf 您如何管理表的迁移/创建?是否可以分享您的__init__.py 或更多应用程序?
  • @teelf,不是好消息:我在本地复制了您的所有代码并运行 import 没有错误:In [1]: from server.schedule.models import Task \n In [2]: 可能错误在其他地方......
  • models.py 中是否还有您尚未发布的代码?

标签: python postgresql flask flask-sqlalchemy


【解决方案1】:

尝试添加

 __table_args__ = {'extend_existing': True} 

__tablename__= 下的用户类

干杯

【讨论】:

  • 你是从哪里学到的,你能在 SQLalchemy 文档中分享更多关于案例的地方吗? (你的回答正是我需要的)
  • 虽然这在某些情况下很有用,但通常不需要这样做,这表明表定义是多次创建的——通常是偶然的。将其作为通用的“只需将其复制并粘贴到您的代码”解决方案会产生误导,只会隐藏真正的错误。
  • 这是 sqlalchemy 文档的link,其中提到了 __table_args__ dict。
【解决方案2】:

如果您的预先存在的数据库中还没有数据,另一种选择是删除它,在没有表的情况下重新创建它。然后交互式地运行您的“models.py”脚本(您需要在底部添加一些代码以允许这样做),然后在交互式 Python 控制台中执行“db.create_all()”,它应该根据您的类。

【讨论】:

    猜你喜欢
    • 2010-11-23
    • 2018-05-24
    • 2012-06-04
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 2017-05-11
    • 2011-03-09
    • 2016-08-28
    相关资源
    最近更新 更多