所以我很难用标题中的技术解决我的问题。
我有几个玩家加入了一个游戏。所以一个游戏有很多玩家。我正在使用 python flask、带有 sqlite 后端的 sqlalchemy 和 marshmallow 进行编组。
这些是相关文件:
database.py - 初始化数据库
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
engine = create_engine('sqlite:///database.sqlite3', convert_unicode=True)
db_session = scoped_session(sessionmaker(bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()
def init_db():
from dom.database.model_game import Game
from dom.database.model_player import Player
Base.metadata.create_all(bind=engine)
这是我的播放器模型和架构:
from sqlalchemy import Column, String, Integer, Boolean, ForeignKey
from sqlalchemy.orm import relationship
from flask_marshmallow import Schema
from marshmallow_sqlalchemy import SQLAlchemySchema, auto_field
from marshmallow_sqlalchemy.fields import Nested
from dom.database.database import Base, db_session
class Player(Base):
__tablename__ = "player"
id = Column(Integer, primary_key=True)
name = Column(String, nullable=False)
nickname = Column(String, nullable=True)
in_game = Column(Boolean, nullable=True)
# belongs to one
game_id = Column(Integer, ForeignKey(
'game.id', ondelete="SET NULL"), nullable=True)
game = relationship("Game", back_populates="players")
# THIS WILL WORK FINE
# class PlayerSchema(Schema):
# class Meta:
# fields = ("id", "name", "nickname", "in_game", "game_id")
class PlayerSchema(SQLAlchemySchema):
class Meta:
sqla_session = db_session
model = Player
load_instance = True
id = auto_field()
name = auto_field
nickname = auto_field()
in_game = auto_field()
game_id = auto_field()
player_schema = PlayerSchema()
players_schema = PlayerSchema(many=True)
这是我的游戏模型和架构:
from sqlalchemy import Column, String, Integer
from sqlalchemy.orm import relationship
from marshmallow_sqlalchemy import SQLAlchemySchema, auto_field
from marshmallow_sqlalchemy.fields import Nested
from dom.database.database import Base, db_session
from dom.database.model_player import Player, PlayerSchema
class Game(Base):
__tablename__ = "game"
id = Column(Integer, primary_key=True)
game = Column(String, nullable=False)
variant = Column(String, nullable=False)
active_player = Column(Integer, nullable=False)
throw_round = Column(Integer, nullable=False)
game_state = Column(String, nullable=False)
# has many
players = relationship(Player, back_populates="game")
class GameSchema(SQLAlchemySchema):
class Meta:
sqla_session = db_session
model = Game
load_instance = True
id = auto_field()
game = auto_field()
variant = auto_field()
active_player = auto_field()
throw_round = auto_field()
game_state = auto_field()
players = Nested(PlayerSchema, many=True)
game_schema = GameSchema()
games_schema = GameSchema(many=True)
因此,如果在我的播放器模型中使用代码中的行标记为“这将正常工作”的模式,我可以解决关系。但是随着我将继续实现与玩家相关的其他关系,例如个人资料图片,我将根据我在游戏模式中所做的更改玩家模式,从而导致此堆栈跟踪:
Traceback (most recent call last):
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/ext/declarative/clsregistry.py", line 311, in _resolve_name
rval = d[token]
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/util/_collections.py", line 739, in __missing__
self[key] = val = self.creator(key)
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/ext/declarative/clsregistry.py", line 290, in _access_cls
return self.fallback[key]
KeyError: 'Game'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "/home/patrick/projects/theallnewdom/server/run.py", line 2, in <module>
from dom import app, socketio
File "/home/patrick/projects/theallnewdom/server/dom/__init__.py", line 9, in <module>
from dom.api.routes import initialize_routes
File "/home/patrick/projects/theallnewdom/server/dom/api/routes.py", line 1, in <module>
from dom.api.game import GamesApi, GameApi
File "/home/patrick/projects/theallnewdom/server/dom/api/game.py", line 4, in <module>
from dom.database.model_game import Game, games_schema, game_schema
File "/home/patrick/projects/theallnewdom/server/dom/database/model_game.py", line 8, in <module>
from dom.database.model_player import Player, PlayerSchema
File "/home/patrick/projects/theallnewdom/server/dom/database/model_player.py", line 46, in <module>
class PlayerSchema(SQLAlchemySchema):
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/marshmallow/schema.py", line 120, in __new__
klass._declared_fields = mcs.get_declared_fields(
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/marshmallow_sqlalchemy/schema/sqlalchemy_schema.py", line 94, in get_declared_fields
fields.update(mcs.get_auto_fields(fields, converter, opts, dict_cls))
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/marshmallow_sqlalchemy/schema/sqlalchemy_schema.py", line 104, in get_auto_fields
{
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/marshmallow_sqlalchemy/schema/sqlalchemy_schema.py", line 105, in <dictcomp>
field_name: field.create_field(
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/marshmallow_sqlalchemy/schema/sqlalchemy_schema.py", line 28, in create_field
return converter.field_for(model, column_name, **self.field_kwargs)
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/marshmallow_sqlalchemy/convert.py", line 170, in field_for
prop = model.__mapper__.get_property(property_name)
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/orm/mapper.py", line 2043, in get_property
configure_mappers()
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/orm/mapper.py", line 3255, in configure_mappers
mapper._post_configure_properties()
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/orm/mapper.py", line 1950, in _post_configure_properties
prop.init()
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/orm/interfaces.py", line 196, in init
self.do_init()
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/orm/relationships.py", line 1983, in do_init
self._process_dependent_arguments()
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/orm/relationships.py", line 2045, in _process_dependent_arguments
self.target = self.entity.persist_selectable
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/util/langhelpers.py", line 883, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/orm/relationships.py", line 1950, in entity
argument = self.argument()
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/ext/declarative/clsregistry.py", line 315, in _resolve_name
self._raise_for_name(name, err)
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/ext/declarative/clsregistry.py", line 293, in _raise_for_name
util.raise_(
File "/home/patrick/projects/theallnewdom/server/.venv/lib/python3.8/site-packages/sqlalchemy/util/compat.py", line 178, in raise_
raise exception
sqlalchemy.exc.InvalidRequestError: When initializing mapper mapped class Player->player, expression 'Game' failed to locate a name ('Game'). If this is a class name, consider adding this relationship() to the <class 'dom.database.model_player.Player'> class after both dependent classes have been defined.
有人可以向我指出如何改变以使其正常工作的大致方向吗?
在此先感谢,最好的问候,帕特里克