使用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 学习-41.Flask-RESTPlus 入门到放弃
Flask-restplus:如何使用“allOf”操作定义嵌套模型?