关注documentation,我已定义并填充了以下表格,但尚未定义任何关系。
class CountryAssociation(Base):
__tablename__ = 'Country_Region_Mapping'
country_id = Column(Integer, ForeignKey('countries.uid'), primary_key=True)
region_id = Column(Integer, ForeignKey('regions.uid'), primary_key=True)
region = relationship('Region', back_populates='country')
country = relationship('Countries', back_populates='region')
extra_data = Column(String(50))
class Countries(Base):
__tablename__ = 'countries'
uid = Column(Integer, primary_key=True)
countryname = Column('English_short_name',
String(255), unique=True, nullable=False)
region = relationship('CountryAssociation',
back_populates='country')
class Region(Base):
__tablename__ = 'regions'
uid = Column(Integer, primary_key=True)
region = Column(String(255), unique=True, nullable=False)
country = relationship('CountryAssociation',
back_populates='region')
我现在想要在表之间创建多对多的关系。 docs
Base = automap_base() #reflecting the orm way
engine = create_engine('sqlite:///mydatabse.db')
Base.prepare(engine, reflect=True)
Session = sessionmaker(bind=engine)
session = Session()
table_countries = Base.classes.countries
table_regions = Base.classes.regions
r = session.query(table_regions).filter(table_regions.region == "Western Europe").first()
c = session.query(table_countries).filter(table_countries.English_short_name == "Germany").first()
c.region.append(r) # this fails with
AttributeError:'countries'对象没有属性'region'
然而这有效:
c.countryname # Germany
我不知道我在这里做错了什么(初学者)......
答案 0 :(得分:0)
由于您已将association object pattern与extra_data
一起使用,因此自动relationship detection无法将Country_Region_Mapping
识别为secondary table of a many to many:
- 如果表包含两个且恰好两个
醇>ForeignKeyConstraint
个对象,并且此表中的所有列都是这两个ForeignKeyConstraint
对象的成员,则该表将被假定为“辅助”表,并且无法直接映射。
换句话说:并非Country_Region_Mapping
中的所有列都是外键约束的成员,因此表不是次要,因此不会创建多对多的关系。
你忽略的另一件事是naming scheme。如果您有一个工作的辅助表,那么创建的关系将是named regions_collection
by default(因为复数表名称)。
在regions
和Country_Region_Mapping
以及countries
和Country_Region_Mapping
之间创建的多对一/一对多关系会发生什么:
In [22]: table_countries.country_region_mapping_collection
Out[22]: <sqlalchemy.orm.attributes.InstrumentedAttribute at 0x7f2d600fb258>
In [23]: table_regions.country_region_mapping_collection
Out[23]: <sqlalchemy.orm.attributes.InstrumentedAttribute at 0x7f2d600fbaf0>
In [28]: table_country_region_mapping.countries
Out[28]: <sqlalchemy.orm.attributes.InstrumentedAttribute at 0x7f2d535a2990>
In [29]: table_country_region_mapping.regions
Out[29]: <sqlalchemy.orm.attributes.InstrumentedAttribute at 0x7f2d535a2938>
请注意,由于多个表命名,Country_Region_Mapping
上的标量关系属性也有多个命名。
考虑到这些,您需要添加一个新的关联:
In [36]: c.country_region_mapping_collection.append(
...: Base.classes.Country_Region_Mapping(countries=c, regions=r))