无法覆盖Sqlalchemy继承类中的方法

时间:2017-02-17 01:43:02

标签: python sqlalchemy

我正在努力解决一些我怀疑非常简单的事情,因为这是一个明显的用例,我在sqlalchemy文档中看不到任何相关内容。

我已经设置了SourceArchive类,它继承自SourceFile。根据此页面,他们使用联合表方法:http://docs.sqlalchemy.org/en/latest/orm/inheritance.html

import os
import json
from sqlalchemy import Column, ForeignKey, Integer, String, orm
import py7zlib
import filesys_ops
from db_base import Base

# Base = declarative_base()


class SourceDir(Base):

    __tablename__ = 'source_dirs'

    id = Column(Integer, primary_key=True)
    dir_path = Column(String)
    # files = relationship(SourceFile)

    def __init__(self, dir_path):
        self.dir_path = dir_path

    def get_files(self):
        return filesys_ops.read_files(self.dir_path)


class SourceFile(Base):

    __tablename__ = 'source_file'

    # Create a 'rom_names' variable, verify on instantiation and then add to obj.
    # Then have consistent 'get_names' method across subclasses
    id = Column(Integer, primary_key=True)
    full_path = Column(String)
    name = Column(String)
    # type = Column(String)
    parent_dir_id = Column(Integer, ForeignKey('source_dirs.id'))
    type = Column(String(50))

    def __init__(self, file_path, parent_dir):
        self.full_path = file_path
        # path, self.name = os.path.split(self.full_path)
        # self.type = magic.from_file(self.full_path)
        self.parent_dir_id = parent_dir.id

    def ext(self):
        base_name, extension = os.path.splitext(self.name)
        return extension

    # @orm.reconstructor
    # def init_on_load(self):
    #     pass

    def get_rom_names(self):
        print('super')
        return [self.name]

    __mapper_args__ = {
        'polymorphic_identity': 'source_file',
        'polymorphic_on': type
    }


class SourceArchive(SourceFile):

    __tablename__ = 'source_archive'

    id = Column(Integer, ForeignKey('source_file.id'),     primary_key=True)
    members_json = Column(String)

    def __init__(self, file_path, parent_dir):
        super().__init__(file_path, parent_dir)
        file = open(file_path, 'rb')
        archive = py7zlib.Archive7z(file)
        members = archive.getnames()
        self.members_json = json.dumps(members)
        # print(self.members_json)
            # print(type(self.members_json))
            # print(self.members_json)

    def get_rom_names(self):
        print('or')
        # print('**** - ' + self.members)
        if type(json.loads(self.members_json)) is list:
            return json.loads(self.members_json)
        else:
            return [json.loads(self.members_json)]

    def extractall(self, target_dir):
        for name in self.members:
            self.extract_member(name, target_dir)

    def extract_member(self, member_name, path):
        output_path = os.path.join(path, member_name)
        output_dir = os.path.dirname(output_path)
        filesys_ops.validate_dir(output_dir, create=True)
        outfile = open(output_path, 'wb')
        outfile.write(self.archive.getmember(member_name).read())
        outfile.close()

        __mapper_args__ = {
            'polymorphic_identity': 'source_archive',
        }

使用SourceFile和SourceArchive对象的组合填充数据库后,我使用以下代码来检索它们:

all_files = with_polymorphic(SourceFile, SourceArchive)

query = session.query(all_files)

source_files = query.all()

这只返回SourceFile对象,结果是对'get_roms'方法的任何调用都会调用SourceFile实现。

在以前版本的代码中,我没有使用链接教程中的样板文件,而只是像普通Python一样接近类继承,在某些情况下共享表,而在其他情况下则没有。然后,我可以将所有对象作为SourceFiles返回,或者全部作为SourceArchives返回,只是取决于我查询的对象,具有相同的结果(尽管也可以在SourceFile对象上调用SourceArchive的get_roms实现)。

如果有人可以提供帮助,我会非常感激,

0 个答案:

没有答案