Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在SQLAlchemy(polimorphic)中创建与多个表的声明性关系_Python_Sqlalchemy - Fatal编程技术网

Python 如何在SQLAlchemy(polimorphic)中创建与多个表的声明性关系

Python 如何在SQLAlchemy(polimorphic)中创建与多个表的声明性关系,python,sqlalchemy,Python,Sqlalchemy,如何在SQLAlchemy(polimorphic)中创建与多个表的声明性关系 我有一个日志对象,它反映数据库中的日志表。它在相关表中保存类型和id(作为外键)。我需要创建声明性类来映射这些表 数据库的结构我不能改变,也不能创建额外的关联表。但我知道对象的标识符 在代码示例的底部可以看到我想要得到的东西 engine = create_engine('sqlite://', echo=True) metadata = MetaData(bind=engine) Base = declarativ

如何在SQLAlchemy(polimorphic)中创建与多个表的声明性关系

我有一个日志对象,它反映数据库中的日志表。它在相关表中保存类型和id(作为外键)。我需要创建声明性类来映射这些表

数据库的结构我不能改变,也不能创建额外的关联表。但我知道对象的标识符

在代码示例的底部可以看到我想要得到的东西

engine = create_engine('sqlite://', echo=True)
metadata = MetaData(bind=engine)
Base = declarative_base(bind=metadata)
DBSession = sessionmaker(bind=engine, autocommit=False, expire_on_commit=False)
session = DBSession()


class Person(Base):
    __abstract__ = True


class Manager(Person):
    __tablename__ = 'managers'

    identifier = '01'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    manager_data = Column(String(40))

    __mapper_args__ = {
        'polymorphic_identity': identifier,
    }


class Engineer(Person):
    __tablename__ = 'engineers'

    identifier = '02'

    id = Column(Integer, primary_key=True)
    name = Column(String(50))
    engineer_info = Column(String(40))

    __mapper_args__ = {
        'polymorphic_identity': identifier,
    }


class Journal(Base):
    __tablename__ = 'journal'

    identifier = '03'

    id = Column(Integer, primary_key=True)
    date = Column(Date)

    type = Column(String(50))
    person_id = Column(Integer)
    person = relationship()     # can’t figure out this relationship

    __mapper_args__ = {
        'polymorphic_on': type,
        'with_polymorphic': '*'
    }


if __name__ == '__main__':

    metadata.create_all()

    en1 = Engineer(id=1)
    mn1 = Manager(id=2)

    session.add_all([en1, mn1])
    session.commit()

    j1 = Journal(person=en1)
    # -> INSERT INTO Journal (type, person_id) VALUES (’02’, 1)

    j2 = Journal(person=mn1)
    # -> INSERT INTO Journal (type, person_id) VALUES (‘01’, 2)

    for row in session.query(Journal):
            print(row, row.person)
    # -> [<Journal …>, <Manager …>]
    # -> [<Journal …>, <Engineer …>]

    for row in session.query(Journal).filter(Journal.type == Manager.identifier):
            print(row, row.person)
    # -> [<Journal …>, <Manager …>]
engine=create\u engine('sqlite://',echo=True)
元数据=元数据(绑定=引擎)
Base=声明性_Base(bind=元数据)
DBSession=sessionmaker(bind=engine,autocommit=False,expire\u on\u commit=False)
session=DBSession()
班级人员(基本):
__抽象=真
班级经理(人):
__tablename_uuu='managers'
标识符='01'
id=列(整数,主键=True)
名称=列(字符串(50))
manager_数据=列(字符串(40))
__映射器参数={
“多态_标识”:标识符,
}
班主任(人):
__tablename_uuu=‘工程师’
标识符='02'
id=列(整数,主键=True)
名称=列(字符串(50))
工程师信息=列(字符串(40))
__映射器参数={
“多态_标识”:标识符,
}
班级日志(基本):
__tablename_uu='journal'
标识符='03'
id=列(整数,主键=True)
日期=列(日期)
类型=列(字符串(50))
person\u id=列(整数)
person=relationship()#无法理解此关系
__映射器参数={
“多态”:类型,
“with_多态”:“*”
}
如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu':
metadata.create_all()
en1=工程师(id=1)
mn1=经理(id=2)
session.add_all([en1,mn1])
session.commit()
j1=日记账(人员=en1)
#->插入日记账(类型、人员id)值('02',1)
j2=日记账(人员=mn1)
#->插入日记账(类型、人员id)值('01',2)
对于会话中的行。查询(日记帐):
打印(行,行,人)
# -> [, ]
# -> [, ]
对于session.query(Journal.filter)(Journal.type==Manager.identifier)中的行:
打印(行,行,人)
# -> [, ]
感谢迈克·拜耳找到的解决方案

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    identifier = '01'

    id = Column('id', Integer, primary_key=True)
    name = Column('name', String(50), nullable=False)

class Order(Base):
    __tablename__ = 'orders'
    identifier = '02'

    id = Column('id', Integer, primary_key=True)
    description = Column('description', String(50), nullable=False)


class Address(Base):
    __tablename__ = 'addresses'

    id = Column('id', Integer, primary_key=True)
    addressable_id = Column('addressable_id', Integer)
    addressable_type = Column('addressable_type', String(50))
    street = Column('street', String(100))
    city = Column('city', String(50))
    country = Column('country', String(50))

    def __init__(self, type):
        self.addressable_type = type

    member = property(lambda self: getattr(self, '_backref_%s' % self.addressable_type))


def addressable(cls, name, uselist=True):
    """addressable 'interface'."""

    def create_address(self):
        a = Address(cls.identifier)
        if uselist:
            getattr(self, name).append(a)
        else:
            setattr(self, name, a)
        return a

    cls.create_address = create_address

    mapper = class_mapper(cls)
    table = mapper.local_table

    # no constraints.  therefore define constraints in an ad-hoc fashion.
    primaryjoin = and_(
        list(table.primary_key)[0] == Address.addressable_id,
        Address.addressable_type == cls.identifier
    )

    foreign_keys = [Address.addressable_id]

    mapper.add_property(name, relation(
        Address,
        primaryjoin=primaryjoin, uselist=uselist, foreign_keys=foreign_keys,
        backref=backref(
            '_backref_%s' % cls.identifier,
            primaryjoin=list(table.primary_key)[0] == Address.addressable_id,
            foreign_keys=foreign_keys,
            # lazy="joined"   # Joined strategy
        )
    )
                        )


addressable(User, 'addresses', uselist=True)
addressable(Order, 'address', uselist=False)

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

u1 = User()
u1.name = 'bob'

o1 = Order()
o1.description = 'order 1'

a1 = u1.create_address()
a1.street = '123 anywhere street'
a2 = u1.create_address()
a2.street = '345 orchard ave'

a3 = o1.create_address()
a3.street = '444 park ave.'

sess = create_session(bind=e)
sess.add(u1)
sess.add(o1)
sess.flush()

# query addresses and get relative objects

for address in sess.query(Address):
    print("Street", address.street, "Member", address.member)
感谢迈克·拜耳找到的解决方案

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    identifier = '01'

    id = Column('id', Integer, primary_key=True)
    name = Column('name', String(50), nullable=False)

class Order(Base):
    __tablename__ = 'orders'
    identifier = '02'

    id = Column('id', Integer, primary_key=True)
    description = Column('description', String(50), nullable=False)


class Address(Base):
    __tablename__ = 'addresses'

    id = Column('id', Integer, primary_key=True)
    addressable_id = Column('addressable_id', Integer)
    addressable_type = Column('addressable_type', String(50))
    street = Column('street', String(100))
    city = Column('city', String(50))
    country = Column('country', String(50))

    def __init__(self, type):
        self.addressable_type = type

    member = property(lambda self: getattr(self, '_backref_%s' % self.addressable_type))


def addressable(cls, name, uselist=True):
    """addressable 'interface'."""

    def create_address(self):
        a = Address(cls.identifier)
        if uselist:
            getattr(self, name).append(a)
        else:
            setattr(self, name, a)
        return a

    cls.create_address = create_address

    mapper = class_mapper(cls)
    table = mapper.local_table

    # no constraints.  therefore define constraints in an ad-hoc fashion.
    primaryjoin = and_(
        list(table.primary_key)[0] == Address.addressable_id,
        Address.addressable_type == cls.identifier
    )

    foreign_keys = [Address.addressable_id]

    mapper.add_property(name, relation(
        Address,
        primaryjoin=primaryjoin, uselist=uselist, foreign_keys=foreign_keys,
        backref=backref(
            '_backref_%s' % cls.identifier,
            primaryjoin=list(table.primary_key)[0] == Address.addressable_id,
            foreign_keys=foreign_keys,
            # lazy="joined"   # Joined strategy
        )
    )
                        )


addressable(User, 'addresses', uselist=True)
addressable(Order, 'address', uselist=False)

e = create_engine("sqlite://", echo=True)
Base.metadata.create_all(e)

u1 = User()
u1.name = 'bob'

o1 = Order()
o1.description = 'order 1'

a1 = u1.create_address()
a1.street = '123 anywhere street'
a2 = u1.create_address()
a2.street = '345 orchard ave'

a3 = o1.create_address()
a3.street = '444 park ave.'

sess = create_session(bind=e)
sess.add(u1)
sess.add(o1)
sess.flush()

# query addresses and get relative objects

for address in sess.query(Address):
    print("Street", address.street, "Member", address.member)