web-dev-qa-db-fra.com

la table 'roles_users' est déjà définie pour cette instance MetaData

bonjour iam essayant d'obtenir une information currnet_user dans mes vues 

et j'inclus depuis users.models import * 

puis dans mon code, retournez return current_user;

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

et une fois que je lance mon serveur sa dit 

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.

et dans mon modèle j'ai 

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'))

et jusqu'à présent, je ne comprenais pas pourquoi cette erreur et comment la résoudre exactement, merci de me guider pour résoudre le problème

10
TheBlueDragon

Cela dépend de ce que vous voulez faire, essayez-vous de:

  1. supprimer l'ancienne classe et la repalquer avec un nouveau mappage de classe? Ou,
  2. Garder l'ancienne classe et juste redémarrer votre application?

Dans le premier cas, avec votre exemple ci-dessus, essayez de lancer la ligne suivante avant de définir vos classes:

db.metadata.clear()

La raison en est la première fois que vous déclarez un mappage SQLAlchemy en définissant une classe python. La définition de la classe est enregistrée dans l'objet de métadonnées, afin d'éviter les conflits causés par le mappage de plusieurs définitions sur la même table.

Lorsque vous appelez la méthode clear(), vous effacez toutes les définitions de table conservées en mémoire par l'objet Metadata, ce qui vous permet de les déclarer à nouveau. 

Dans le second cas, lorsque vous venez de redémarrer l'application , J'écrirais un test pour voir si la table existe déjà à l'aide de la méthode reflect :

db.metadata.reflect(engine=engine)

Où engine correspond à votre connexion à la base de données créée à l'aide de create_engine(). Vérifiez si vos tables existent déjà et définissez la classe uniquement si la table n'est pas définie.

3
Spcogg the second

C'est un an de retard, mais si quelqu'un ne trouve pas la solution dans les réponses données, cela peut résoudre le problème -

J'ai eu ce même problème avec ma classe qui a été héritée de db.Model (de flask_sqlalchemy).

Mon code ressemblait à ceci - 

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

Résolu en spécifiant la propriété abstract / sur True dans la liste de variables de classe. Ajoutez-le dans la liste de variables de classe comme ceci et cela devrait fonctionner -

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

J'ai vu cette même erreur en utilisant le cahier Jupyter. J'importais des classes de table sqlalchemy à partir d'une bibliothèque stockée sur disque et il y avait un bogue dans la définition. Après avoir corrigé le bogue, j'ai relancé l'importation et j'ai vu cette erreur. Le simple redémarrage du noyau jupyter, puis la réexécution de l'importation ont résolu le problème. 

0
Scott McCormick

J'ai eu cette erreur lorsque j'avais créé une nouvelle classe en copiant-collant une classe précédente. Il s’est avéré que j’avais oublié de changer le __tablename__; j’avais donc deux classes avec la même propriété __tablename__. Cela a provoqué l'erreur et a modifié la propriété pour la résoudre.

0
N. Quest