SQLAlchemy Create All Table выдает ошибку NoReferencedTable - PullRequest
0 голосов
/ 10 октября 2019

Я прошу fask_sqlalchemy создать таблицу для меня. Но я получаю ошибку NoReferencedTable.

Вот код для моделей:

 from db import db


class Artist(db.Model):
    __tablename__ = 'artists'
    ArtistId = db.Column(db.Integer, primary_key=True)
    Name = db.Column(db.NVARCHAR(120))

class Album(db.Model):
    ___tablename__ = 'albums'
    AlbumId = db.Column(db.Integer, primary_key=True)
    Title = db.Column(db.NVARCHAR(160), nullable=False)
    ArtistId = db.Column(db.ForeignKey('artists.ArtistId'), nullable=False, index=True)

    artist = db.relationship('Artist')
class Employee(db.Model):
    __tablename__ = 'employees'

    EmployeeId = db.Column(db.Integer, primary_key=True)
    LastName = db.Column(db.NVARCHAR(20), nullable=False)
    FirstName = db.Column(db.NVARCHAR(20), nullable=False)
    Title = db.Column(db.NVARCHAR(30))
    ReportsTo = db.Column(db.ForeignKey('employees.EmployeeId'), index=True)
    BirthDate = db.Column(db.DateTime)
    HireDate = db.Column(db.DateTime)
    Address = db.Column(db.NVARCHAR(70))
    City = db.Column(db.NVARCHAR(40))
    State = db.Column(db.NVARCHAR(40))
    Country = db.Column(db.NVARCHAR(40))
    PostalCode = db.Column(db.NVARCHAR(10))
    Phone = db.Column(db.NVARCHAR(24))
    Fax = db.Column(db.NVARCHAR(24))
    Email = db.Column(db.NVARCHAR(60))

    parent = db.relationship('Employee', remote_side=[EmployeeId])

class Genre(db.Model):
    __tablename__ = 'genres'

    GenreId = db.Column(db.Integer, primary_key=True)
    Name = db.Column(db.NVARCHAR(120))

class MediaType(db.Model):
    __tablename__ = 'media_types'

    MediaTypeId = db.Column(db.Integer, primary_key=True)
    Name = db.Column(db.NVARCHAR(120))


class Playlist(db.Model):
    __tablename__ = 'playlists'

    PlaylistId = db.Column(db.Integer, primary_key=True)
    Name = db.Column(db.NVARCHAR(120))

    tracks = db.relationship('Track', secondary='playlist_track')

class Customer(db.Model):
    __tablename__ = 'customers'

    CustomerId = db.Column(db.Integer, primary_key=True)
    FirstName = db.Column(db.NVARCHAR(40), nullable=False)
    LastName = db.Column(db.NVARCHAR(20), nullable=False)
    Company = db.Column(db.NVARCHAR(80))
    Address = db.Column(db.NVARCHAR(70))
    City = db.Column(db.NVARCHAR(40))
    State = db.Column(db.NVARCHAR(40))
    Country = db.Column(db.NVARCHAR(40))
    PostalCode = db.Column(db.NVARCHAR(10))
    Phone = db.Column(db.NVARCHAR(24))
    Fax = db.Column(db.NVARCHAR(24))
    Email = db.Column(db.NVARCHAR(60), nullable=False)
    SupportRepId = db.Column(db.ForeignKey('employees.EmployeeId'), index=True)

    employee = db.relationship('Employee')


class Invoice(db.Model):
    __tablename__ = 'invoices'

    InvoiceId = db.Column(db.Integer, primary_key=True)
    CustomerId = db.Column(db.ForeignKey('customers.CustomerId'), nullable=False, index=True)
    InvoiceDate = db.Column(db.DateTime, nullable=False)
    BillingAddress = db.Column(db.NVARCHAR(70))
    BillingCity = db.Column(db.NVARCHAR(40))
    BillingState = db.Column(db.NVARCHAR(40))
    BillingCountry = db.Column(db.NVARCHAR(40))
    BillingPostalCode = db.Column(db.NVARCHAR(10))
    Total = db.Column(db.Numeric(10, 2), nullable=False)

    customer = db.relationship('Customer')


class Track(db.Model):
    __tablename__ = 'tracks'

    TrackId = db.Column(db.Integer, primary_key=True)
    Name = db.Column(db.NVARCHAR(200), nullable=False)
    AlbumId = db.Column(db.ForeignKey('albums.AlbumId'), index=True)
    MediaTypeId = db.Column(db.ForeignKey('media_types.MediaTypeId'), nullable=False, index=True)
    GenreId = db.Column(db.ForeignKey('genres.GenreId'), index=True)
    Composer = db.Column(db.NVARCHAR(220))
    Milliseconds = db.Column(db.Integer, nullable=False)
    Bytes = db.Column(db.Integer)
    UnitPrice = db.Column(db.Numeric(10, 2), nullable=False)

    album = db.relationship('Album')
    genre = db.relationship('Genre')
    media_type = db.relationship('MediaType')


class InvoiceItem(db.Model):
    __tablename__ = 'invoice_items'

    InvoiceLineId = db.Column(db.Integer, primary_key=True)
    InvoiceId = db.Column(db.ForeignKey('invoices.InvoiceId'), nullable=False, index=True)
    TrackId = db.Column(db.ForeignKey('tracks.TrackId'), nullable=False, index=True)
    UnitPrice = db.Column(db.Numeric(10, 2), nullable=False)
    Quantity = db.Column(db.Integer, nullable=False)

    invoice = db.relationship('Invoice')
    track = db.relationship('Track')

Я получаю ошибку:

sqlalchemy.exc.NoReferencedTableError

sqlalchemy. exc.NoReferencedTableError: внешнему ключу, связанному со столбцом «track.AlbumId», не удалось найти таблицу «album», с помощью которой можно сгенерировать внешний ключ для целевого столбца «AlbumId»

Таблица альбомов есть и онатакже есть столбец AlbumId. Я не понимаю эту ошибку.

Нужна помощь в понимании причины этой ошибки.

1 Ответ

0 голосов
/ 10 октября 2019

Я думаю, что вы допустили ошибку в классе вашего альбома. Вы не можете иметь

db.relationship(...)

и

db.Column(db.ForeignKey(...))

в одном классе.

Я думаю, ваши классы Artist и Album должны выглядеть следующим образом:

class Artist(db.Model):
    __tablename__ = 'artists'
    ArtistId = db.Column(db.Integer, primary_key=True)
    Name = db.Column(db.NVARCHAR(120))
    Albums = db.relationship('Album', backref="artist"))
    # Instead of 'Albums', you can name it whatever you want.
    # It's just a way to access albums from an artist.

class Album(db.Model):
    ___tablename__ = 'albums'
    AlbumId = db.Column(db.Integer, primary_key=True)
    Title = db.Column(db.NVARCHAR(160), nullable=False)
    ArtistId = db.Column(db.ForeignKey('artists.ArtistId'), nullable=False, index=True)

Благодаря этому вы сможете получить доступ к альбомам исполнителя в классе Artiste и наоборот.

Таким образом, если вы хотите получить доступ к альбомам исполнителя, вы можетесделать что-то вроде этого:

artist = Artist(...)
artist.Albums
# It will automatically return albums from this artist

и наоборот.

Предлагаю вам посмотреть эти два видео:

...