SQLAlchemy: NoForeignKeysError - PullRequest
       1

SQLAlchemy: NoForeignKeysError

0 голосов
/ 24 июня 2019

Я создаю две таблицы и связываю их, используя отношения SQLAlchemy (используя SQLite в качестве моей БД)

class Album(Base):
    __tablename__ = 'albums'
    id = Column(INTEGER, primary_key=True, unique=True, autoincrement=True, nullable=False)
    name = Column(TEXT)
    tracks = relationship('Track', back_populates='albums')

class Track(Base):
    __tablename__ = 'tracks'
    id = Column(INTEGER, primary_key=True, unique=True, autoincrement=True, nullable=False)
    name = Column(TEXT)
    albums = relationship('Album', back_populates='tracks')

def insert_data(metadata, path, ext):
    session = get_session() # returns SQLAlchemy session
    tracks = get_or_create(session,
                           Track,
                           name=metadata['title']
                           )
    _ = get_or_create(session,
                      Album,
                      name=metadata['album'],
                      tracks=tracks
                      )


def get_instance(session, model, permutation):
    try:
        return session.query(model).filter_by(**permutation).first()
    except NoResultFound:
        return None


def create_instance(session, model, permutation):
    try:
        instance = model(**permutation)
        session.add(instance)
        session.flush()
    except Exception as msg:
        log.error(f'model:{model}, args:{permutation} -> msg:{msg}')
        session.rollback()
        raise msg
    return instance


def get_or_create(session, model, **metadata):
    data_permutations = [dict(zip(metadata, value)) for value in product(*metadata.values())]
    ret = []
    for permutation in data_permutations:
        instance = get_instance(session, model, permutation)
        if instance is None:
            instance = create_instance(session, model, permutation)
        ret.append(instance)
    session.commit()
    return ret

insert_metadata(metadata, path, ext)

метаданные выглядят так:

{
 'name': ['foo'],
 'data': ['bar', 'baz'],
 ...
}

Может иметь неограниченное количествоколичество ключей, которые могут иметь списки любой длины в качестве значений.Поэтому я создаю все возможные результаты (перестановки) этих данных и сохраняю их как список уникальных диктовок, например:

[{'name': 'foo', 'data': 'bar'}, {'name': 'foo', 'data': 'baz'}]

Теперь, когда я вызываю insert_data, я получаю следующее сообщение:

sqlalchemy.exc.NoForeignKeysError: Can't find any foreign key relationships between 'albums' and 'tracks'.

Traceback показывает, что функция, которая вызывает исключение, является get_instance.Я подозреваю, что это как-то связано с моим запросом, так как я дважды проверил создание таблицы по документации и другим вопросам переполнения стека, и синтаксис кажется правильным.

Как мне нужно изменитьмой запрос (см. блок try в get_instance), чтобы программа не вылетала?Или ошибка в другом месте?

1 Ответ

0 голосов
/ 24 июня 2019

Проблема заключалась в том, что в таблице «track» отсутствовал столбец album_id:

    album_id = Column(INTEGER, ForeignKey('albums.id'))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...