使用flask-restplus在flask-SQLAlchemy中创建多对多关联表时出错

Posted

技术标签:

【中文标题】使用flask-restplus在flask-SQLAlchemy中创建多对多关联表时出错【英文标题】:Error creating many to many Association table in flask-SQLAlchemy with flask-restplus 【发布时间】:2020-04-22 16:22:30 【问题描述】:

我正在尝试使用使用 flask-SQLAlchemy 的关联表在我的 flask-restplus api 中实现多对多关系。我只是在学习一些教程,但我认为我错过了一些东西。

这是我的代码: 请注意,承诺.py 和 user.py 位于名为 models 的同一文件夹中

质押.py

from db import db
from datetime import datetime

class PledgeModel(db.Model):
    __tablename__ = 'pledge'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(20))
    created = db.Column(db.Date)
    due = db.Column(db.Date)
    amount = db.Column(db.Integer)
    balance = db.Column(db.Integer)


def __init__(self,name,created,due,amount,balance,user_id):
    self.name = name
    self.created = created
    self.due = due
    self.amount = amount
    self.balance = balance
    self.user_id = user_id

user.py

from db import db
from datetime import datetime
from models.pledge import PledgeModel

commits = db.Table(
'commits',
db.Column('user_id', db.Integer, db.ForeignKey('UserModel.id')),
db.Column('pledge_id', db.Integer, db.ForeignKey('PledgeModel.id'))
)

class UserModel(db.Model):
    __tablename__ = "users"

    id = db.Column(db.Integer, primary_key = True)
    username  = db.Column(db.String(20), unique = True)
    password  = db.Column(db.String(20))
    firstname = db.Column(db.String(20))
    lastname  = db.Column(db.String(20))
    age       = db.Column(db.Integer)
    birthday  = db.Column(db.Date)
    address   = db.Column(db.String(50))
    pledges   = db.relationship('PledgeModel', secondary = 'commits', backref = db.backref('users', lazy = 'dynamic'))



    def __init__(self,username, password, firstname, lastname, age, birthday, address ):
        self.username   = username
        self.password   = password
        self.firstname  = firstname
        self.lastname   = lastname
        self.age        = age
        self.birthday   = birthday
        self.address    = address

这是我运行烧瓶应用程序的 app.py

from flask import Flask,render_template
from flask_restful import Api
from flask_jwt import JWT
from security  import authenticate, identity
from resources.user import Register, UserList
from models.user import UserModel
from models.pledge import PledgeModel
from db import db

app = Flask(__name__)
app.secret_key = "everboy"
db.init_app(app)
api = Api(app)
jwt = JWT(app, authenticate, identity)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']    = False


@app.before_first_request
def create_table():
    db.create_all()

api.add_resource(Register, '/Register')
api.add_resource(UserList, '/Userlist')

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

这是发生的错误,似乎没有导入UserModel但关联表与UserModel在同一个文件中

[2020-04-23 00:14:55,505] ERROR in app: Exception on /Register [POST]
Traceback (most recent call last):
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\flask\app.py", line 2447, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\flask\app.py", line 1945, in full_dispatch_request
    self.try_trigger_before_first_request_functions()
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\flask\app.py", line 1993, in try_trigger_before_first_request_functions
    func()
  File "app.py", line 22, in create_table
    db.create_all()
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 1033, in create_all
    self._execute_for_all_tables(app, bind, 'create_all')
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\flask_sqlalchemy\__init__.py", line 1025, in _execute_for_all_tables
    op(bind=self.get_engine(app, bind), **extra)
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\sqlalchemy\sql\schema.py", line 4321, in create_all
    ddl.SchemaGenerator, self, checkfirst=checkfirst, tables=tables
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\sqlalchemy\engine\base.py", line 2058, in _run_visitor
    conn._run_visitor(visitorcallable, element, **kwargs)
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\sqlalchemy\engine\base.py", line 1627, in _run_visitor
    visitorcallable(self.dialect, self, **kwargs).traverse_single(element)
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\sqlalchemy\sql\visitors.py", line 144, in traverse_single
    return meth(obj, **kw)
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\sqlalchemy\sql\ddl.py", line 754, in visit_metadata
    [t for t in tables if self._can_create_table(t)]
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\sqlalchemy\sql\ddl.py", line 1159, in sort_tables_and_constraints
    dependent_on = fkc.referred_table
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\sqlalchemy\sql\schema.py", line 3242, in referred_table
    return self.elements[0].column.table
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 883, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "C:\Users\ASUS\Desktop\Dalbong\POI\venv\lib\site-packages\sqlalchemy\sql\schema.py", line 2049, in column
    tablekey,
sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'commits.user_id' could not find table 'UserModel' with which to generate a foreign key to target column 'id'

【问题讨论】:

【参考方案1】:

db.ForeignKey 参数接受表名而不是模型名,因此如果您将其从 db.ForeignKey('UserModel.id') 更改为 db.ForeignKey('users.id'),它将起作用。 Here 是关于如何声明关系的 Sqlalchemy 文档

【讨论】:

我已经尝试过了,但同样的错误,我认为问题在于首先运行的执行,在这种情况下,关联表在声明两个模型之前首先运行

以上是关于使用flask-restplus在flask-SQLAlchemy中创建多对多关联表时出错的主要内容,如果未能解决你的问题,请参考以下文章

flask-restplus 知识点

flask-restplus 知识点

Flask-RESTPlus系列Part2:响应编组

Flask-RESTPlus系列Part3:请求解析

Flask 学习-41.Flask-RESTPlus 入门到放弃

Flask 学习-49.Flask-RESTX 使用 namespaces 命名空间