我正在努力解决一些我怀疑非常简单的事情,因为这是一个明显的用例,我在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实现)。
如果有人可以提供帮助,我会非常感激,