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

时间:2016-06-19 15:18:08

标签: python sqlalchemy

你好我试图在我的观点中获得一个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'))

直到现在我都不明白为什么我会收到这个错误以及如何解决这个错误请指导我解决问题

12 个答案:

答案 0 :(得分:5)

TL; DR

  • 如果在尝试将烧瓶蓝图注册到应用程序时遇到此错误,请检查模型导入路径在导入模型的所有蓝图中是否一致

例如

  • 蓝图1:from A.B.C import Model A
  • 蓝图2:from .B.C import Model A(这会引发错误,导入路径在导入相同模型的所有蓝图中应该是一致的。因此应该是from A.B.C import Model A

我没有深入研究这个问题以找出原因,但是我猜想SQLAlchemy使用其导入的名称空间来管理Model,并且当定义了不同的名称空间但模型相同时会引发错误。

答案 1 :(得分:4)

这取决于你想做什么,你想尝试:

  1. 删除旧类并使用新的类映射重新生成它?或者,
  2. 保留旧课程,然后重启您的应用程序?
  3. 在第一种情况下使用上面的示例尝试在定义类之前运行以下行:

    db.metadata.clear()
    

    原因是第一次通过定义python类声明SQLAlchemy Mapping时,类的定义被保存到元数据对象,以防止多个定义映射到同一个表所引起的冲突。

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

    在您重新启动应用时的第二种情况 我会使用reflect method编写测试以查看表是否已存在:

    db.metadata.reflect(engine=engine)
    

    其中engine是使用create_engine()创建的数据库连接,并查看您的表是否已存在,并且只有在表未定义时才定义该类。

答案 2 :(得分:4)

我叫雅各布。我有同样的情况。

问题是这样的:当您以相同的代码导入父表和子表时,就会发生这种情况。然后导入CHILD表,CHILD表也将父表的结构也带入元数据。因此,您无需再次导入PARENT表。

解决方案是:您需要重新排列在代码中导入ORM结构的顺序。顺序基于父子关系。

示例:以下内容会产生错误:

import CHILD_ORM
import PARENT_ORM   

重新安排顺序如下,以防止发生错误:

import PARENT_ORM   
import CHILD_ORM

答案 3 :(得分:3)

它迟了一年,但如果有人在给定答案中找不到解决方案,可能会解决问题 -

我的同类问题与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

答案 4 :(得分:2)

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

答案 5 :(得分:2)

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

答案 6 :(得分:1)

在开发模式下运行flask应用程序时出现此错误:

FLASK_ENV=development flask run

flask的动态重载功能显然确实可以按您期望的那样重载元数据实例。按照“第二次Spcogg”的建议重新启动该应用程序可以为我解决此问题!

答案 7 :(得分:0)

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

答案 8 :(得分:0)

尝试添加:

  

__table_args__ = {'extend_existing': True}

__tablename__下方

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

答案 9 :(得分:0)

很可能是导入错误。

只是在您的一个组件中多次导入了 roles_users 模型。

如果您导入了多个组件,其中已经导入了所需模型,则可能会发生这种情况

示例:

from schemas.user import UserSchema # have `from models.user import User` inside
from blocs.users import UsersBLOC # have `from models.user import User` inside

答案 10 :(得分:0)

我在导入和明确定义外键关系中的模型时遇到了这个问题(例如在官方文档的 examples 中)

不好:

ForeignKey(User.id)

好吧(不是导入模型):

ForeignKey("user.id")

答案 11 :(得分:-4)

只需为roles_users添加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)
相关问题