繁体   English   中英

在 sqlalchemy 中加入两个没有关系的表

[英]Joining two table without relantioships in sqlalchemy

这是我的问题。 我有三张桌子。

一个名为 Project 的项目只有一个名为 id 的列(这在整个系统中必须是唯一的)。
一个称为 ServiceAwarenessProject,它与 Project.id 具有一对一的关系。
一个叫做 CorporateVPNProject,它与 Project.id 是一对一的关系

我正在使用 sqlalchemy ORM,因此代码如下所示:

class Project(SqlAlchemyBase):
    __tablename__ = 'project'

    id = Column(Integer, primary_key=True, autoincrement=True)


class ServiceAwarenessProject(SqlAlchemyBase):
    __tablename__ = 'sa_project'

    id = Column(Integer, primary_key=True)
    project_id = Column(Integer, ForeignKey(Project.id))
    mop_url = Column(String, nullable=False)
    expiration_date = Column(Datetime, index=True)


class CorporateVPNProject(SqlAlchemyBase):
    __tablename__ = 'wvpn_project'

    id = Column(Integer, primary_key=True)
    project_id = Column(Integer, ForeignKey(Project.id))
    mop_url = Column(String, nullable=False)

我是这样设计我的表的,所以我可以保证在整个系统中我有唯一的 project_ids。 我的问题是我不知道如何将这些表连接在一起以根据 project_id 查找项目。 为了暂时解决这个问题,我使用名为 get_project_by_id 的函数查询这两个表。 有没有更聪明的方法来解决这个问题?

class ProjectService:
    @staticmethod
    def create_project_id():
        session = DbSessionFactory.create_session()
        result = session.query(Project.id).order_by(desc(Project.id)).first()

        if result:
            result = result[0]
            if str(result)[:8] == datetime.datetime.now().strftime('%Y%m%d'):
                project_id = str(result)[:8] + '{:03d}'.format(int(str(result)[8:]) + 1)
                new_project = Project(id=project_id)
                session.add(new_project)
                session.commit()
                return project_id

        project_id = datetime.datetime.now().strftime('%Y%m%d') + '001'
        new_project = Project(id=project_id)
        session.add(new_project)
        session.commit()
        return project_id

    @staticmethod
    def get_project_by_id(project_id):
        session = DbSessionFactory.create_session()
        result = session.query(ServiceAwarenessProject) \
            .filter(ServiceAwarenessProject.project_id == project_id) \
            .first()

        if result:
            return result

        result = session.query(CorporateVPNProject) \
            .filter(CorporateVPNProject.project_id == project_id) \
            .first()
        if result:
            return result

    def create_serviceawareness_project(self):
        session = DbSessionFactory.create_session()
        project_id = self.create_project_id()
        new_project = ServiceAwarenessProject(project_id=project_id, mop_url='http://www.thepacketwizards.com/1')
        session.add(new_project)
        session.commit()
        return new_project

    def create_corporatevpn_project(self):
        session = DbSessionFactory.create_session()
        project_id = self.create_project_id()
        new_project = CorporateVPNProject(project_id=project_id, mop_url='http://www.thepacketwizards.com/wvpn')
        session.add(new_project)
        session.commit()
        return new_project

谢谢!

按照@Ilja Everilä 的建议,我像这样设计了表,只使用了连接表继承

class Project(SqlAlchemyBase):
    __tablename__ = 'project'

    id = Column(Integer, primary_key=True)
    created_on = Column(DateTime, default=datetime.datetime.now)
    updated_on = Column(DateTime, default=datetime.datetime.now, onupdate=datetime.datetime.now)
    project_url = Column(String(60))
    mop_url = Column(String(60))
    input_url = Column(String(60))
    type = Column(String(60))
    __mapper_args__ = {
        'polymorphic_identity': 'project',
        'polymorphic_on': type
    }


class ServiceAwarenessProject(Project):
    __tablename__ = 'sa_project'

    id = Column(Integer, ForeignKey('project.id'), primary_key=True)
    expiration_date = Column(DateTime)
    __mapper_args__ = {
        'polymorphic_identity': 'ServiceAwareness',
    }


class CorporateVPNProject(Project):
    __tablename__ = 'wvpn_project'

    id = Column(Integer, ForeignKey('project.id'), primary_key=True)
    client_name = Column(String(60))
    __mapper_args__ = {
        'polymorphic_identity': 'CorporateVPN',
    }

现在,要查询数据库,我必须使用with_polymorphic ,因此我可以获得每行不同的 Tables 实例。

class ProjectService:
    @staticmethod
    def create_project_id():
        session = DbSessionFactory.create_session()
        result = session.query(Project.id).order_by(desc(Project.id)).first()
        print(result)
        if result:
            result = result[0]
            if str(result)[:8] == datetime.datetime.now().strftime('%Y%m%d'):
                project_id = str(result)[:8] + '{:03d}'.format(int(str(result)[8:]) + 1)
                return project_id

        project_id = datetime.datetime.now().strftime('%Y%m%d') + '001'
        return project_id

    def create_serviceawareness_project(self):
        session = DbSessionFactory.create_session()
        project_id = self.create_project_id()
        new_project = ServiceAwarenessProject(id=project_id,
                                              project_url='http://project',
                                              expiration_date=datetime.datetime.now() + datetime.timedelta(days=365),
                                              mop_url='http://mop',
                                              input_url='http://url',
                                              type='ServiceAwareness')

        session.add(new_project)
        session.commit()
        session.add(new_project)

        return new_project

    def create_corporatevpn_project(self):
        session = DbSessionFactory.create_session()
        project_id = self.create_project_id()
        new_project = CorporateVPNProject(id=project_id,
                                          project_url='http://project',
                                          client_name='TIM',
                                          mop_url='http://mop',
                                          input_url='http://url',
                                          type='CorporateVPN')

        session.add(new_project)
        session.commit()
        session.add(new_project)

        return new_project

    @staticmethod
    def get_project_by_id(project_id):
        session = DbSessionFactory.create_session()
        query = session.query(with_polymorphic(Project, [ServiceAwarenessProject, CorporateVPNProject])).filter(or_(
            ServiceAwarenessProject.id == project_id,
            CorporateVPNProject.id == project_id
        )).first()
        return query

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM