SQLAlchemy, несомненно, очень мощный, но документация подразумевает, что предполагает много предшествующих знаний и по теме отношений, смешивает между backref
и новостями -предоставляемые методы back_populates()
, которые я нахожу очень запутанными.SQLAlchemy: __init __() принимает 1 позиционный аргумент, но 2 дано (многие из многих)
Следующая модельная диаграмма представляет собой точное зеркало руководства в документации, касающейся Association Objects for many-to-many relationships. Вы можете видеть, что комментарии по-прежнему идентичны комментариям в оригинальной статье, и я только изменил фактический код.
class MatchTeams(db.Model):
match_id = db.Column(db.String, db.ForeignKey('match.id'), primary_key=True)
team_id = db.Column(db.String, db.ForeignKey('team.id'), primary_key=True)
team_score = db.Column(db.Integer, nullable="True")
# bidirectional attribute/collection of "user"/"user_keywords"
match = db.relationship("Match",
backref=db.backref("match_teams",
cascade="all, delete-orphan")
)
# reference to the "Keyword" object
team = db.relationship("Team")
class Match(db.Model):
id = db.Column(db.String, primary_key=True)
# Many side of many to one with Round
round_id = db.Column(db.Integer, ForeignKey('round.id'))
round = db.relationship("Round", back_populates="matches")
# Start of M2M
# association proxy of "match_teams" collection
# to "team" attribute
teams = association_proxy('match_teams', 'team')
def __repr__(self):
return '<Match: %r>' % (self.id)
class Team(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String, nullable=False)
goals_for = db.Column(db.Integer)
goals_against = db.Column(db.Integer)
wins = db.Column(db.Integer)
losses = db.Column(db.Integer)
points = db.Column(db.Integer)
matches_played = db.Column(db.Integer)
def __repr__(self):
return '<Team %r with ID: %r>' % (self.name, self.id)
Но этот фрагмент, который должен связать экземпляр команды find_liverpool
с экземпляром матча find_match
(оба стереотипных объектов), не работает:
find_liverpool = Team.query.filter(Team.id==1).first()
print(find_liverpool)
find_match = Match.query.filter(Match.id=="123").first()
print(find_match)
find_match.teams.append(find_liverpool)
И выводит следующее:
Traceback (most recent call last):
File "/REDACT/temp.py", line 12, in <module>
find_match.teams.append(find_liverpool)
File "/REDACT/lib/python3.4/site-packages/sqlalchemy/ext/associationproxy.py", line 609, in append
item = self._create(value)
File "/REDACT/lib/python3.4/site-packages/sqlalchemy/ext/associationproxy.py", line 532, in _create
return self.creator(value)
TypeError: __init__() takes 1 positional argument but 2 were given
<Team 'Liverpool' with ID: 1>
<Match: '123'>
Вы будете необходимо предоставить дополнительную информацию. Что порождает эту ошибку? Это не может быть фрагмент, который вы опубликовали, потому что если первая строка подняла ошибку, то 'find_liverpool' не будет заполнен, но это явно так. Пожалуйста, покажите полный код и трассировку. –
@ DanielRoseman код, который я опубликовал, - это то, что порождает ошибку. Я добавил полную трассу. find_liverpool заполняется до 'TypeError', но по какой-то причине после него выводятся отпечатки. – zerohedge