python - Sqlalchemy 关系字段返回无
问题描述
我有以下型号:
class DictionaryItem(Base):
__tablename__ = 'dictionary_items'
id = Column(Integer, primary_key=True)
text = Column(String, nullable=True)
phonetic_symbols = Column(String, nullable=True)
fgner_entity = Column(String, nullable=True)
status = Column(String, default="waiting")
user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
user = relationship("User", back_populates="dictionary_items")
data_type_id = Column(Integer, ForeignKey('data_types.id'), nullable=False)
data_type = relationship("DataType", back_populates="dictionary_items", lazy="joined")
# can null if manually add
sns_raw_data_id = Column(Integer, ForeignKey('sns_raw_data.id'), nullable=True)
sns_raw_data = relationship("SnsRawData", back_populates="dictionary_items")
language_id = Column(Integer, ForeignKey('languages.id'), nullable=False, default=1)
language = relationship("Language", back_populates="dictionary_items")
created_at = Column(DateTime, nullable=False, default=func.now())
updated_at = Column(DateTime, nullable=False,
default=func.now(), onupdate=func.now())
deleted_at = Column(DateTime, nullable=True)
def __repr__(self):
return 'id: {}'.format(self.id)
@classmethod
def check_is_exists(cls, user_id, text, dictionary_id=None):
if dictionary_id is not None:
count = session.query(DictionaryItem).filter(DictionaryItem.user_id==user_id, DictionaryItem.text==text, DictionaryItem.deleted_at == None, DictionaryItem.id != dictionary_id).count()
else:
count = session.query(DictionaryItem).filter(DictionaryItem.user_id==user_id, DictionaryItem.text==text, DictionaryItem.deleted_at == None).count()
return count > 0
@classmethod
def add_dictionary_item(cls, text=None, phonetic_symbols=None, fgner_entity=None, user_id=None, data_type_id=None, language_id=None, sns_raw_data_id=None):
if not DictionaryItem.check_is_exists(user_id, text):
new_dictionary_item = DictionaryItem(
text=text,
phonetic_symbols=phonetic_symbols,
fgner_entity=fgner_entity,
user_id=user_id,
data_type_id=data_type_id,
language_id=language_id,
sns_raw_data_id=sns_raw_data_id
)
try:
session.add(new_dictionary_item)
session.commit()
session.refresh(new_dictionary_item)
except:
session.rollback()
raise
return new_dictionary_item
else:
return None
Language.dictionary_items = relationship("DictionaryItem", order_by=DictionaryItem.id, back_populates="language")
@event.listens_for(DictionaryItem, 'before_update')
def dictionary_item_before_update(mapper, connection, target):
print("before_update: %d" % target.id)
if target.sns_raw_data_id is not None:
if "language" in target.sns_raw_data.data:
target.language_id = get_language_id_by_language(target.sns_raw_data.data["language"])
if target.language_id is None:
target.language_id = detect_language_id(target.text)
@event.listens_for(DictionaryItem, 'before_insert')
def dictionary_item_before_insert(mapper, connection, target):
print("before_insert: %s" % target.text)
print(target.sns_raw_data, file=sys.stderr)
if target.sns_raw_data_id is not None:
if "language" in target.sns_raw_data.data:
target.language_id = get_language_id_by_language(target.sns_raw_data.data["language"])
if target.language_id is None:
target.language_id = detect_language_id(target.text)
SnsRawData.dictionary_items = relationship("DictionaryItem", order_by=DictionaryItem.id, back_populates="sns_raw_data")
User.dictionary_items = relationship("DictionaryItem", order_by=DictionaryItem.id, back_populates="user")
DataType.dictionary_items = relationship("DictionaryItem", order_by=DictionaryItem.id, back_populates="data_type")
class SnsRawData(Base):
__tablename__ = 'sns_raw_data'
id = Column(Integer, primary_key=True)
data = Column(postgresql.JSON)
status = Column(String, default="waiting")
sns_account_id = Column(Integer, ForeignKey('sns_accounts.id'), nullable=False)
sns_account = relationship("SnsAccount", back_populates="sns_raw_data", lazy="joined")
created_at = Column(DateTime, nullable=False, default=func.now())
updated_at = Column(DateTime, nullable=False,
default=func.now(), onupdate=func.now())
deleted_at = Column(DateTime, nullable=True)
def __repr__(self):
return 'id: {}'.format(self.id)
SnsAccount.sns_raw_data = relationship("SnsRawData", order_by=SnsRawData.id, back_populates="sns_account")
DictionaryItem 通过 sns_raw_data_id 与 SnsRawData 建立关系。
在 DictionaryItem lister_for event('before_insert') 我目前得到 target.sns_raw_data.data 返回 None 但 target.sns_raw_data_id 在我执行插入时返回一个值。
File "/app/models.py", line 230, in dictionary_item_before_insert
if "language" in target.sns_raw_data.data:
AttributeError: 'NoneType' object has no attribute 'data'
当我有它的 Id 时,如何从 SnsRawData 模型访问数据字段?
解决方案
我想通了,它返回 None 因为它是在插入之前运行的,所以开始时没有任何关系,我只需要使用 DictionaryItem 中的 sns_raw_data_id 在 SnsRawData 中查询
@event.listens_for(DictionaryItem, 'before_insert')
def dictionary_item_before_insert(mapper, connection, target):
print("before_insert: %s" % target.text)
if target.sns_raw_data_id is not None:
sns_raw_data = session.query(SnsRawData).filter(SnsRawData.id==target.sns_raw_data_id).first()
if "language" in sns_raw_data.data:
target.language_id = get_language_id_by_language(sns_raw_data.data["language"])
if target.language_id is None:
target.language_id = detect_language_id(target.text)
推荐阅读
- django - 如何在不使用过滤器的情况下获取模型的多个对象?
- r - 将字符串中第 N 次出现的字符替换为其他字符
- c# - 如何解决多表单问题 (CS7036)
- react-native - 如何在 React Native 中使用酶测试 openDrawer?
- java - apache.commons.logging.log 性能没有调试日志代码保护
- java - 如何将两个活动制作到一个文件中?
- f# - f# 将 seq obj 转换为 seq 记录
- javascript - 使用 Content-Type 时 nodejs https 请求抛出错误
- ruby-on-rails - Heroku 上的 WickedPDF 松散样式
- javascript - 是否可以在我可以在同一个 HTML 文件中编辑的 HTML 文件中创建一个 Javascript 对象?