SQLAlchemy:NoForeignKeysError

时间:2019-06-24 16:48:33

标签: python sqlite sqlalchemy

我正在创建两个表,并使用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。我怀疑它与查询有关,因为我对照文档和其他Stack Overflow问题仔细检查了表的创建,并且语法似乎是正确的。

如何更改查询(请参阅get_instance中的try块),以使程序不会崩溃?还是其他地方的错误?

1 个答案:

答案 0 :(得分:0)

问题是表'tracks'缺少列album_id:

    album_id = Column(INTEGER, ForeignKey('albums.id'))