我正在尝试为我的数据库创建 orm 类。 我有一个表歌曲、一个表艺术家和一个表 Song_artist 来修复 m:n 关系。
class Song(Base):
__tablename__ = 'songs'
SONG_ID: Mapped[int] = mapped_column(Integer, primary_key=True, nullable=False, index=True)
ALBUM_ID: Mapped[int] = mapped_column(Integer, ForeignKey('albums.ALBUM_ID'), nullable=False)
GENRE_ID: Mapped[int] = mapped_column(Integer, ForeignKey('genres.GENRE_ID'), nullable=False)
FILE_ID: Mapped[int] = mapped_column(Integer, ForeignKey('files.FILE_ID'), nullable=False)
DURATION: Mapped[int] = mapped_column(Integer)
TITLE: Mapped[str] = mapped_column(String(100))
RELEASE_DATE: Mapped[Date] = mapped_column(Date)
file: Mapped['File'] = relationship(back_populates="song")
album: Mapped['Album'] = relationship(back_populates="song")
genre: Mapped['Genre'] = relationship(back_populates="song")
artist: Mapped[List['Artist']] = relationship(secondary="songs_artists", back_populates="song"
class Artist(Base):
__tablename__ = 'artists'
ARTIST_ID: Mapped[int] = mapped_column(Integer, primary_key=True)
ARTIST_NAME: Mapped[str] = mapped_column(String(100))
song: Mapped['Song'] = relationship(secondary="songs_artists",back_populates="artist")
songs_artists = Table(
'songs_artists',
Base.metadata,
Column('SONG_ID', Integer, ForeignKey('songs.SONG_ID'), primary_key=True),
Column('ARTIST_ID', Integer, ForeignKey('artists.ARTIST_ID'), primary_key=True)
)
我收到以下错误消息:
sqlalchemy.exc.InvalidRequestError: When initializing mapper Mapper[Artist(artists)], expression 'songs_artists' failed to locate a name ("name 'songs_artists' is not defined"). If this is a class name, consider adding this relationship() to the <class 'src.database.musicDB.db_model_artist.Artist'> class after both dependent classes have been defined
.
我现在尝试更换桌子几个小时,但无法解决问题。
如有任何帮助,将不胜感激。 谢谢
file
、album
等字段)并包含导入和测试代码songs_artists
)放在模型之前 artists: Mapped[List["Artist"]] = relationship(
secondary="songs_artists", back_populates="songs"
)
songs: Mapped[List["Song"]] = relationship(
secondary="songs_artists", back_populates="artists"
)
工作示例:
from typing import List
from sqlalchemy import Column, ForeignKey, Integer, String, Table, create_engine
from sqlalchemy.orm import (
DeclarativeBase,
Mapped,
mapped_column,
relationship,
sessionmaker,
)
class Base(DeclarativeBase):
pass
songs_artists = Table(
"songs_artists",
Base.metadata,
Column("SONG_ID", Integer, ForeignKey("songs.SONG_ID"), primary_key=True),
Column("ARTIST_ID", Integer, ForeignKey("artists.ARTIST_ID"), primary_key=True),
)
class Song(Base):
__tablename__ = "songs"
SONG_ID: Mapped[int] = mapped_column(
Integer, primary_key=True, nullable=False, index=True
)
# ALBUM_ID: Mapped[int] = mapped_column(Integer, ForeignKey('albums.ALBUM_ID'), nullable=False)
# GENRE_ID: Mapped[int] = mapped_column(Integer, ForeignKey('genres.GENRE_ID'), nullable=False)
# FILE_ID: Mapped[int] = mapped_column(Integer, ForeignKey('files.FILE_ID'), nullable=False)
# DURATION: Mapped[int] = mapped_column(Integer)
TITLE: Mapped[str] = mapped_column(String(100))
# RELEASE_DATE: Mapped[Date] = mapped_column(Date)
# file: Mapped['File'] = relationship(back_populates="song")
# album: Mapped['Album'] = relationship(back_populates="song")
# genre: Mapped['Genre'] = relationship(back_populates="song")
artists: Mapped[List["Artist"]] = relationship(
secondary="songs_artists", back_populates="songs"
)
class Artist(Base):
__tablename__ = "artists"
ARTIST_ID: Mapped[int] = mapped_column(Integer, primary_key=True)
ARTIST_NAME: Mapped[str] = mapped_column(String(100))
songs: Mapped[List["Song"]] = relationship(
secondary="songs_artists", back_populates="artists"
)
engine = create_engine("sqlite://")
Base.metadata.create_all(bind=engine)
session_maker = sessionmaker(bind=engine)
with session_maker() as session:
song_1 = Song(TITLE="s 1")
song_2 = Song(TITLE="s 2")
artist_1 = Artist(ARTIST_NAME="a 1", songs=[song_1])
artist_2 = Artist(ARTIST_NAME="a 2", songs=[song_1, song_2])
session.add_all((song_1, song_2, artist_1, artist_2))
session.commit()