2015-01-07 19 views
6

Tôi đang sử dụng Flask và SQLAlchemy. Tôi đã sử dụng lớp cơ sở trừu tượng của riêng mình và kế thừa. Khi tôi cố gắng sử dụng các mô hình của mình trong vỏ trăn, tôi nhận được lỗi sau:Phép thừa kế SQLAlchemy không hoạt động

>>> 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. 

Làm cách nào để khắc phục sự cố này?

Code:

manage.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") 
+1

Hãy thử loại bỏ '__mapper_args__', đó là vô nghĩa trong ví dụ của bạn anyway. – davidism

+0

@davidism Nó không tạo ra bất kỳ sự khác biệt nào. –

+0

Hai thứ có thể hữu ích (mặc dù tôi chưa có cơ hội thử nghiệm chúng): a) khi khởi tạo 'SQLAlchemy()' sử dụng ứng dụng Flask của bạn (ví dụ 'db = SQLAlchemy (app)'; b) 'người dùng' là một [từ khoá được bảo lưu trong PostgreSQL] (http://www.postgresql.org/docs/current/static/sql-keywords-appendix.html), vì vậy có thể '__tablename__ =" users "' có thể kết thúc trong một số xung đột . – cuducos

Trả lời

12

Hãy thử thêm

__table_args__ = {'extend_existing': True} 

đến lớp người dùng của bạn ngay unde r __tablename__=

cổ vũ

+4

Bạn đã học được điều này ở đâu và bạn có thể chia sẻ tài liệu SQLalchemy trong trường hợp được nói về nhiều hơn không? (Bạn trả lời chỉ là những gì tôi cần) –

+3

Trong khi điều này hữu ích trong một số trường hợp, nói chung điều này không cần thiết và là dấu hiệu cho thấy các định nghĩa bảng được tạo nhiều lần - thường là do ngẫu nhiên. Ném nó như là một giải pháp "chỉ cần sao chép và dán mã này vào mã của bạn" là gây hiểu lầm và chỉ ẩn các lỗi thực sự. –

Các vấn đề liên quan