Ошибка создания таблицы ассоциации «многие ко многим» в flask -SQLAlchemy с flask -restplus - PullRequest
0 голосов
/ 22 апреля 2020

Я пытаюсь реализовать отношение «многие ко многим» в моем flask -restplus api, используя таблицу ассоциаций, используя flask -SQLAlchemy. Я просто следую некоторым учебникам, но думаю, что мне чего-то не хватает.

Вот мой код: обратите внимание, что pledge.py и user.py находятся в одной папке с именем models

pledge.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, где я запускаю flask приложение

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 Ответ

0 голосов
/ 23 апреля 2020

Аргумент db.ForeignKey принимает имя таблицы вместо названия модели, поэтому, если вы измените его с db.ForeignKey('UserModel.id') на db.ForeignKey('users.id'), оно будет работать. Здесь - документы Sqlalchemy о том, как объявлять отношения

...