SQLAlchemy空外键返回attribute

2024-05-14 18:05:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我试着自学炼金术。我在处理有关系的表时遇到了一个问题,但是外键有时是空的。代码如下:

from sqlalchemy.orm import sessionmaker, relationship
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:///:memory:')
Base = declarative_base()
Session = sessionmaker(bind=engine)
session = Session()

class Brewer(Base):
    __tablename__ = "brewer_table"
    brewer_id = Column(Integer, primary_key=True)
    brewery_name = Column(String)

class Style(Base):
    __tablename__ = 'style_table'
    style_id = Column(Integer, primary_key=True)
    style_name = Column(String)

class Beer(Base):
    __tablename__ = 'beer_table'
    beer_id = Column(Integer, primary_key=True)
    beer_name = Column(String)
    beer_brewer = Column(Integer, ForeignKey("brewer_table.brewer_id"), nullable=True)
    beer_style = Column(Integer, ForeignKey("style_table.style_id"), nullable=True)
    brewer = relationship(Brewer)
    style = relationship(Style)

Base.metadata.create_all(engine)

light_beer = Style(style_name="light beer")
stout = Style(style_name="stout")
ipa = Style(style_name="india pale ale")
session.add_all([light_beer, stout, ipa])

budweiser = Brewer(brewery_name="Budweiser")
stone = Brewer(brewery_name="Stone")
session.add_all([budweiser, stone])

bud_light = Beer(beer_name="Bud Light", brewer=budweiser, style=light_beer)
stone_ipa = Beer(beer_name="Stone IPA", brewer=stone)
stone_americano = Beer(beer_name="Americano Stout", brewer=stone, style=ipa)
session.add_all([bud_light, stone_ipa, stone_americano])

session.commit()

query = session.query(Beer)
for beer in query:
    print(f"name: {beer.beer_name}, brewery: {beer.brewer.brewery_name}, style: {beer.style.style_name}")

如你所见,我没有第二瓶啤酒的款式。当我运行这个时,它抛出异常:AtributeError:“NoneType”没有对象属性“style\u name”。如果我给第二瓶啤酒加上一种风格,就可以了。在

我试过用几种不同的方法测试这个值是否为none,但是我没能做到。在

我不知道这个关系是否必须比我在这里定义的更复杂,或者我是否从根本上误解了如何允许外键中的空值。任何人能提供任何帮助都将不胜感激。在


Tags: nameidtruebasestylesessiontablecolumn
1条回答
网友
1楼 · 发布于 2024-05-14 18:05:49

{{cd2}能够处理^{cd2}的代码。在

一种方法是测试f-string中的style属性,如果是None或空字符串,则生成一些默认输出。在

for beer in query:
    print(f"name: {beer.beer_name}, brewery: {beer.brewer.brewery_name}, style: {beer.style.style_name if beer.style else 'MISSING'}")

生产

^{pr2}$

这不是很优雅,而且很容易忘记每次打印啤酒细节时都要添加这张支票。如果您要经常使用这个f-string,请考虑将它作为其__str__方法添加到啤酒模型中,如下所示:

class Beer(Base):

    ....

    def __str__(self):
        # This method is called whenever *str* is called on a Beer instance. 
        # Split long string in two and wrap in brackets so Python will
        # automatically concatenate them
        return (f"name: {self.beer_name}, brewery: {self.brewer.brewery_name}, "
                f"style: {self.style.style_name if self.style else 'MISSING'}")

for beer in query:
    print(beer)


name: Bud Light, brewery: Budweiser, style: light beer
name: Stone IPA, brewery: Stone, style: MISSING
name: Americano Stout, brewery: Stone, style: india pale ale

相关问题 更多 >

    热门问题