已为此MetaData实例定义表'roles_users'

问题描述 投票:18回答:7

你好我试图在我的视图中获取currnet_user信息

并且我包括来自users.models import *

然后在我的代码中返回return current_user;

@app.route('/panel')
@login_required
def access_panel():
    return current_user.email;

并且一旦我运行服务器,它就会说

Traceback (most recent call last):
  File "manage.py", line 6, in <module>
    from nadel import app
  File "/Users/tbd/Desktop/Projects/nadel/__init__.py", line 27, in <module>
    from users import views
  File "/Users/tbd/Desktop/Projects/nadel/users/views.py", line 5, in <module>
    from users.models import *
  File "/Users/tbd/Desktop/Projects/nadel/users/models.py", line 8, in <module>
    db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))
  File "/Library/Python/2.7/site-packages/flask_sqlalchemy/__init__.py", line 67, in _make_table
    return sqlalchemy.Table(*args, **kwargs)
  File "/Library/Python/2.7/site-packages/sqlalchemy/sql/schema.py", line 398, in __new__
    "existing Table object." % key)
sqlalchemy.exc.InvalidRequestError: Table 'roles_users' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns on an existing Table object.

并且在我的模型中我有

from nadel import db
from flask.ext.security import UserMixin, RoleMixin


# Define models
roles_users = db.Table('roles_users',
        db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
        db.Column('role_id', db.Integer(), db.ForeignKey('role.id')))

class Role(db.Model, RoleMixin):

    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(80), unique=True)
    description = db.Column(db.String(255))

class User(db.Model, UserMixin):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255), unique=True)
    name = db.Column(db.String(255))
    password = db.Column(db.String(255))
    active = db.Column(db.Boolean())
    #confirmed_at = db.Column(db.DateTime())
    last_login_at = db.Column(db.DateTime())
    current_login_at = db.Column(db.DateTime())
    last_login_ip = db.Column(db.String(32))
    current_login_ip = db.Column(db.String(32))
    login_count = db.Column(db.Integer)

    roles = db.relationship('Role', secondary=roles_users,
                            backref=db.backref('users', lazy='dynamic'))

并且到目前为止,我还不明白为什么我会收到此错误以及如何完全解决该错误,请指导我解决此问题

python sqlalchemy
7个回答
8
投票

这取决于您要执行的操作,是否正在尝试:

  1. 删除旧的类,并用新的类映射替换它?或者,
  2. 保留旧课程并重新启动您的应用程序?

在上面的示例中,第一种情况是,在定义类之前尝试运行以下行:

db.metadata.clear()

原因是您第一次通过定义python类来声明SQLAlchemy映射,该类的定义会保存到元数据对象中,以防止将多个定义映射到同一张表而导致冲突。

当调用clear()方法时,清除元数据对象保存在内存中的所有表定义,这使您可以再次声明它们。

在第二种情况下,您只是重新启动应用程序我将使用reflect method

编写测试以查看表是否已存在
db.metadata.reflect(engine=engine)

引擎是您使用create_engine()创建的数据库连接,并查看您的表是否已经存在,并且仅在未定义表的情况下才定义类。


6
投票

尝试添加:

__table_args__ = {'extend_existing': True}

__tablename__的正下方

参考:https://docs.sqlalchemy.org/en/13/orm/extensions/declarative/table_config.html?highlight=table_args


4
投票

晚了一年,但如果有人没有在给定的答案中找到解决方案,则可能可以解决问题-

我的类也有同样的问题,它是从db.Model(flask_sqlalchemy的)继承的。

我的代码看起来像这样-

class MasterDB(db.Model):
    __tablename__ = 'masterdb'
    __table_args__ = {'schema': 'schema_any'}
    ...
    ...

通过在类变量列表中将abstract属性指定为True来解决。像这样将其添加到类变量列表中,它应该可以工作-

class MasterDB(db.Model):
    __tablename__ = 'masterdb'
    __table_args__ = {'schema': 'schema_any'}
    __abstract__ = True

2
投票

当我通过复制粘贴上一个类来创建新类时遇到此错误。原来我忘记了更改__tablename__,所以我有两个具有相同__tablename__属性的类。这导致了错误,并且更改属性解决了它。


2
投票

我有类似的错误。我的问题是导入使用相对导入从两个不同文件继承db.Model的类。 Flask-SQLAlchemy将两个导入映射为两个不同的表定义,并尝试创建两个表。我通过在两个文件中使用绝对导入路径来解决此问题。


0
投票

我使用jupyter笔记本看到了相同的错误。我从存储在磁盘上的库中导入sqlalchemy表类,并且定义中存在错误。修复错误后,我重新运行导入并看到此错误。只需重新启动jupyter内核,然后重新运行导入即可解决此问题。


-2
投票

只需为角色用户添加extend_existing = True,如下所示

# Define models
roles_users = db.Table('roles_users',
    db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
    db.Column('role_id', db.Integer(), db.ForeignKey('role.id')),
    extend_existing=True)
© www.soinside.com 2019 - 2024. All rights reserved.