Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQLalchemy类可以同时具有一对多和一对一的关系吗?_Python_Sqlalchemy_Flask Sqlalchemy - Fatal编程技术网

Python SQLalchemy类可以同时具有一对多和一对一的关系吗?

Python SQLalchemy类可以同时具有一对多和一对一的关系吗?,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我试图将歌曲和收视率之间的一对一关系添加到我的flask模型中,但在运行查询时出错。我已经遵循了中的步骤,但当涉及到sqlalchemy时,我仍然感到迷失。歌曲已经有了一对多的关系,也许它不能同时有一对多和一对一的关系 from application import db association_table = db.Table('association', db.Column('songs_id', db.Integer,

我试图将歌曲和收视率之间的一对一关系添加到我的flask模型中,但在运行查询时出错。我已经遵循了中的步骤,但当涉及到sqlalchemy时,我仍然感到迷失。歌曲已经有了一对多的关系,也许它不能同时有一对多和一对一的关系

from application import db

association_table = db.Table('association',
                             db.Column('songs_id', db.Integer,
                                       db.ForeignKey('songs.id')),
                             db.Column('genres_id', db.Integer,
                                       db.ForeignKey('genres.id'))
                             )


class Rating(db.Model):
    __tablename__ = 'songs_ratings'
    id = db.Column(db.Integer, primary_key=True)
    rating = db.Column(db.Numeric(precision=3, scale=2),
                       index=True, nullable=False)
    song_id = db.Column(db.Integer, db.ForeignKey('songs.id'))
    song = db.relationship("Song",  uselist=False,
                           back_populates="songs_ratings")

    def __repr__(self):
        return '{}'.format(self.rating)


class Song(db.Model):
    __tablename__ = 'songs'
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(80), index=True, unique=True, nullable=False)
    artist = db.Column(db.String(30), primary_key=False,
                       unique=False, nullable=False)
    added = db.Column(db.Date, nullable=False)
    rating = db.relationship("Rating", back_populates="songs")
    genres = db.relationship(
        "Genre", secondary=association_table, backref=db.backref('songs'))

    def __repr__(self):
        return '{};{};{}'.format(self.title, self.artist, self.added)


class Genre(db.Model):
    __tablename__ = 'genres'
    id = db.Column(db.Integer, primary_key=True)
    category = db.Column(db.String(80), index=True,
                         unique=True, nullable=False)

    def __repr__(self):
        return '{}'.format(self.category)
错误

运行代码时出现的错误

---------------------------------------------------------------------------
InvalidRequestError                       Traceback (most recent call last)
<ipython-input-7-99ffacdf2d91> in <module>
----> 1 query = db.session.query(Rating, Song).filter(Rating.id==Song.id)
      2 df = pd.read_sql_query(query, db.engine)
      3 df

<string> in query(self, *entities, **kwargs)

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\session.py in query(self, *entities, **kwargs)
   2066         """
   2067 
-> 2068         return self._query_cls(entities, self, **kwargs)
   2069 
   2070     def _identity_lookup(

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\query.py in __init__(self, entities, session)
    173 
    174         self.session = session
--> 175         self._set_entities(entities)
    176 
    177     def _set_propagate_attrs(self, values):

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\query.py in _set_entities(self, entities)
    187                 post_inspect=True,
    188             )
--> 189             for ent in util.to_list(entities)
    190         ]
    191 

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\query.py in <listcomp>(.0)
    187                 post_inspect=True,
    188             )
--> 189             for ent in util.to_list(entities)
    190         ]
    191 

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\sql\coercions.py in expect(role, element, apply_propagate_attrs, argname, post_inspect, **kw)
    166                     if insp is not None:
    167                         if post_inspect:
--> 168                             insp._post_inspect
    169                         try:
    170                             resolved = insp.__clause_element__()

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\util\langhelpers.py in __get__(self, obj, cls)
   1158             if obj is None:
   1159                 return self
-> 1160             obj.__dict__[self.__name__] = result = self.fget(obj)
   1161             obj._memoized_keys |= {self.__name__}
   1162             return result

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\mapper.py in _post_inspect(self)
   2095 
   2096         """
-> 2097         self._check_configure()
   2098 
   2099     @HasMemoized.memoized_attribute

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\mapper.py in _check_configure(self)
   1872     def _check_configure(self):
   1873         if self.registry._new_mappers:
-> 1874             _configure_registries({self.registry}, cascade=True)
   1875 
   1876     def _post_configure_properties(self):

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\mapper.py in _configure_registries(registries, cascade)
   3382             # the order of mapper compilation
   3383 
-> 3384             _do_configure_registries(registries, cascade)
   3385         finally:
   3386             _already_compiling = False

~\AppData\Local\Programs\Python\Python37\lib\site-packages\sqlalchemy\orm\mapper.py in _do_configure_registries(registries, cascade)
   3417                 )
   3418                 e._configure_failed = mapper._configure_failed
-> 3419                 raise e
   3420 
   3421             if not mapper.configured:

InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'mapped class Rating->songs_ratings'. Original exception was: Mapper 'mapped class Song->songs' has no property 'songs_ratings'
---------------------------------------------------------------------------
InvalidRequestError回溯(最近一次呼叫上次)
在里面
---->1 query=db.session.query(Rating,Song.filter)(Rating.id==Song.id)
2 df=pd.read\u sql\u查询(查询,db.engine)
3 df
在查询中(自我、*实体、**kwargs)
查询中的~\AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\orm\session.py(self,*entities,**kwargs)
2066         """
2067
->2068返回self.\u查询\u cls(实体、self、**kwargs)
2069
2070定义标识查找(
~\AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\orm\query.py in\uuuuuu init\uuuu(self,entities,session)
173
174 self.session=会话
-->175自组实体(实体)
176
177定义集传播属性(自身、值):
~AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\orm\query.py in\u set\u entities(self,entities)
187事后检查=正确,
188             )
-->189用于使用对象列表中的ent(实体)
190         ]
191
(.0)中的~\AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\orm\query.py
187事后检查=正确,
188             )
-->189用于使用对象列表中的ent(实体)
190         ]
191
expect中的~\AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\sql\impressions.py(角色、元素、应用传播属性、argname、后期检查、**kw)
166如果insp不是无:
167如果进行后检查:
-->168督察
169尝试:
170已解决=检验条款元素()
获取(self,obj,cls)中的~\AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\util\langhelpers.py
1158如果obj为无:
1159回归自我
->1160 obj.\uuuuu dict\uuuuu[self.\uuuuuuuu name\uuuuuuuu]=结果=self.fget(obj)
1161 obj._memonized_keys |={self.uu name_uuuu}
1162返回结果
~\AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\orm\mapper.py in\u post\u inspect(self)
2095
2096         """
->2097自我检查配置()
2098
2099@hasmomeized.memomeized_属性
~\AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\orm\mapper.py in\u check\u configure(self)
1872 def检查配置(自):
1873如果自注册。新映射程序:
->1874_配置_注册表({self.registry},cascade=True)
1875
1876定义后配置属性(自):
\u configure\u注册表中的~\AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\orm\mapper.py(注册表,级联)
3382#地图编纂的顺序
3383
->3384\u do\u configure\u注册表(注册表,级联)
3385最后:
3386 _已_编译=False
\u do\u configure\u注册表中的~\AppData\Local\Programs\Python\Python37\lib\site packages\sqlalchemy\orm\mapper.py(注册表,级联)
3417                 )
3418 e._configure_failed=映射器。_configure_failed
->3419上升e
3420
3421如果未配置mapper.configured:
InvalidRequestError:一个或多个映射程序未能初始化-无法继续初始化其他映射程序。触发映射器:“映射类分级->歌曲分级”。最初的例外是:映射器“映射类歌曲->歌曲”没有“歌曲”属性

该代码几乎没有问题:

  • 关系的命名应与
    后填充的
    匹配。你有:
    • 歌曲
      /
      歌曲评级
      在一个关系中,以及
    • 评级
      /
      歌曲
      在另一个规范中
    只需将其清理如下:

    class Rating(db.Model):
        # ...
        song_id = db.Column(db.Integer, db.ForeignKey("songs.id"))
        song = db.relationship("Song", back_populates="rating")
    
    class Song(db.Model):
        # ...
        rating = db.relationship("Rating", uselist=False, back_populates="song")
    
  • 上面已经解决的另一个问题是,您需要在第二个关系上使用
    uselist=False
    ,而不是在第一个关系上使用
    uselist=False(虽然它不会造成真正的伤害),因为外键是从
    Rating
    Song

  • 但是,考虑到它是1对1关系,并且没有歌曲就不能存在评级,您可以实际重用您的原始模型,并在
    Rating.id
    列上指定
    ForeignKey
    关系,方法是更改
    Rating
    模型,如下所示:

    class Rating(db.Model):
        __tablename__ = "songs_ratings"
        id = db.Column(db.Integer, db.ForeignKey("songs.id"), primary_key=True)  # <- added FK
        rating = db.Column(db.Numeric(precision=3, scale=2), index=True, nullable=False)
    
        song = db.relationship("Song", back_populates="rating")
    
    等级评定(db.Model):
    __tablename_u=“歌曲\u评级”
    
    id=db.Column(db.Integer,db.ForeignKey(“songs.id”),primary_key=True)#这解决了我所有的问题。谢谢!