2016-09-08 62 views
2

我在工作和學習SQLALCHEMY方面遇到了一些麻煩,我認爲問題在於我的back_populates在關係中,但是我一直無法將其解決。你能指點我正確的方向嗎?SQLAlchemy - 屬性錯誤:_reverse_property

的表創建成功,一切都似乎是爲了直到我試圖創建一個新的MailProvider,這將導致此錯誤:

Traceback (most recent call last): 
    File "C:/Users/Music/.PyCharm2016.2/config/scratches/scratch_7.py", line 71, in <module> 
    gmail = MailProvider(service_provider="gmail.com") 
    File "<string>", line 2, in __init__ 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\orm\instrumentation.py", line 347, in _new_state_if_none 
    state = self._state_constructor(instance, self) 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\util\langhelpers.py", line 754, in __get__ 
    obj.__dict__[self.__name__] = result = self.fget(obj) 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\orm\instrumentation.py", line 177, in _state_constructor 
    self.dispatch.first_init(self, self.class_) 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\event\attr.py", line 256, in __call__ 
    fn(*args, **kw) 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\orm\mapper.py", line 2872, in _event_on_first_init 
    configure_mappers() 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\orm\mapper.py", line 2768, in configure_mappers 
    mapper._post_configure_properties() 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\orm\mapper.py", line 1708, in _post_configure_properties 
    prop.init() 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\orm\interfaces.py", line 183, in init 
    self.do_init() 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\orm\relationships.py", line 1632, in do_init 
    self._generate_backref() 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\orm\relationships.py", line 1866, in _generate_backref 
    self._add_reverse_property(self.back_populates) 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\orm\relationships.py", line 1574, in _add_reverse_property 
    other._reverse_property.add(self) 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\util\langhelpers.py", line 840, in __getattr__ 
    return self._fallback_getattr(key) 
    File "C:\Users\Music\mailtesterV2\lib\site-packages\sqlalchemy\util\langhelpers.py", line 818, in _fallback_getattr 
    raise AttributeError(key) 
AttributeError: _reverse_property 

我的代碼:

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

engine = create_engine('sqlite:///:memory:', echo=True) 
Session = sessionmaker(bind=engine) 

Base = declarative_base() 

class MailProvider(Base): 
    __tablename__ = 'mail_provider' 

    id = Column(Integer, primary_key=True) 
    service_provider = Column(String(250), nullable=False) 

    imap_server = Column(String(250)) 
    imap_server_port = Column(Integer) 
    imap_server_ssl = Column(String(250)) 
    imap_server_port_ssl = Column(Integer) 
    imap_server_use_tls = Column(Boolean) 

    smtp_server = Column(String(250)) 
    smtp_server_port = Column(Integer) 
    smtp_server_ssl = Column(String(250)) 
    smtp_server_port_ssl = Column(Integer) 
    smtp_server_use_tls = Column(Boolean) 

class MailAccount(Base): 
    __tablename__ = "mail_account" 

    id = Column(Integer, primary_key=True) 
    email_address = Column(String(250), nullable=False) 
    imap_username = Column(String(250), nullable=False) 
    imap_password = Column(String(250), nullable=False) 
    smtp_username = Column(String(250), nullable=False) 
    smtp_password = Column(String(250), nullable=False) 
    provider_id = Column(Integer, ForeignKey('mail_provider.id'), nullable=False) 
    provider = relationship("MailProvider", back_populates="service_provider") 
    account_owner = Column(String(250), nullable=False) 

class SentMail(Base): 
    __tablename__ = "sent_mail" 

    id = Column(Integer, primary_key=True) 
    mail_uuid = Column(String(36), nullable=False) 
    time_sent = Column(DateTime(timezone=True), nullable=False) 
    sent_from_id = Column(Integer, ForeignKey('mail_account.id'), nullable=False) 
    sent_from = relationship("MailAccount", back_populates="email_address") 
    sent_to = Column(String(250), nullable=False) 
    msg_subject = Column(String(250)) 
    msg_body = Column(String) 
    send_status = Column(String(500)) 

class ReceivedMail(Base): 
    __tablename__ = "received_mail" 

    id = Column(Integer, primary_key=True) 
    sent_mail_id = Column(Integer, ForeignKey('sent_mail.id'), nullable=False) 
    sent_mail = relationship("SentMail", back_populates="mail_uuid") 
    time_received = Column(DateTime(timezone=True), nullable=False) 


MailProvider.accounts = relationship("MailAccount", back_populates="provider", order_by="MailAccount.id") 
MailAccount.mails_sent = relationship("SentMail", back_populates="mail_uuid", order_by="SentMail.time_sent") 
SentMail.received_mails = relationship("RecievedMail", back_populates="received_time", order_by="RecievedMail.received_time") 

Base.metadata.create_all(engine) 
session = Session() 
gmail = MailProvider(service_provider="gmail.com") 

session.add(gmail) 
session.commit() 

回答

1

關係back_populates參考其他關係,而不是列。

修改後的代碼:

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

engine = create_engine('sqlite:///:memory:', echo=True) 
Session = sessionmaker(bind=engine) 

Base = declarative_base() 

class MailProvider(Base): 
    __tablename__ = 'mail_provider' 

    id = Column(Integer, primary_key=True) 
    service_provider = Column(String(250), nullable=False) 

    imap_server = Column(String(250)) 
    imap_server_port = Column(Integer) 
    imap_server_ssl = Column(String(250)) 
    imap_server_port_ssl = Column(Integer) 
    imap_server_use_tls = Column(Boolean) 

    smtp_server = Column(String(250)) 
    smtp_server_port = Column(Integer) 
    smtp_server_ssl = Column(String(250)) 
    smtp_server_port_ssl = Column(Integer) 
    smtp_server_use_tls = Column(Boolean) 

    accounts = relationship("MailAccount", back_populates="provider") 

class MailAccount(Base): 
    __tablename__ = "mail_account" 

    id = Column(Integer, primary_key=True) 
    email_address = Column(String(250), nullable=False) 
    imap_username = Column(String(250), nullable=False) 
    imap_password = Column(String(250), nullable=False) 
    smtp_username = Column(String(250), nullable=False) 
    smtp_password = Column(String(250), nullable=False) 
    provider_id = Column(Integer, ForeignKey('mail_provider.id'), nullable=False) 
    provider = relationship("MailProvider", back_populates="accounts") 
    account_owner = Column(String(250), nullable=False) 
    mails_sent = relationship("SentMail", back_populates="sent_from", order_by="SentMail.time_sent") 

class SentMail(Base): 
    __tablename__ = "sent_mail" 

    id = Column(Integer, primary_key=True) 
    mail_uuid = Column(String(36), nullable=False) 
    time_sent = Column(DateTime(timezone=True), nullable=False) 
    sent_from_id = Column(Integer, ForeignKey('mail_account.id'), nullable=False) 
    sent_from = relationship("MailAccount", back_populates="mails_sent") 
    sent_to = Column(String(250), nullable=False) 
    msg_subject = Column(String(250)) 
    msg_body = Column(String) 
    send_status = Column(String(500)) 
    received_mails = relationship("ReceivedMail", back_populates="sent_mail", order_by="ReceivedMail.time_received") 

class ReceivedMail(Base): 
    __tablename__ = "received_mail" 

    id = Column(Integer, primary_key=True) 
    sent_mail_id = Column(Integer, ForeignKey('sent_mail.id'), nullable=False) 
    sent_mail = relationship("SentMail", back_populates="received_mails") 
    time_received = Column(DateTime(timezone=True), nullable=False) 

Base.metadata.create_all(engine) 
session = Session() 
gmail = MailProvider(service_provider="gmail.com") 

session.add(gmail) 
session.commit()