使用PGModeler,我们创建了一个模式,然后导出了一些适当的SQL代码。 SQL命令能够填充Postgres数据库中的相应表和行。
从这里开始,我们想要创建声明性的Sqlalchemy模型,因此使用了Sqlautocode。我们在终端上运行了它:
sqlautocode postgresql+psycopg2://username:password@host/db_name -o models.py -d
它按预期生成了我们的表格和相应的模型。到目前为止,零错误。
然后,当进入ipython时,我从models.py导入了所有内容,并尝试创建一个在那里定义的类的实例。突然间,我收到了这个错误:
AttributeError: 'RelationshipProperty' object has no attribute 'c'
这让我困惑了一段时间。讨论这个的其他SO线程的解决方案远不及我的问题(通常与sqlautocode未使用的特定框架或语法有关)。
找到原因后,我决定记录手头的问题。见下文。
答案 0 :(得分:1)
我们的问题仅仅是由于sqlautocode运行时给我们的变量命名错误。具体来说,错误的命名发生在任何具有自身外键的模型中。
以下是一个例子:
#Note that all \"relationship\"s below are now \"relation\"
#it is labeled relationship here because I was playing around...
service_catalog = Table(u'service_catalog', metadata,
Column(u'id', BIGINT(), nullable=False),
Column(u'uuid', UUID(), primary_key=True, nullable=False),
Column(u'organization_id', INTEGER(), ForeignKey('organization.id')),
Column(u'type', TEXT()),
Column(u'name', TEXT()),
Column(u'parent_service_id', BIGINT(), ForeignKey('service_catalog.id')),
)
#Later on...
class ServiceCatalog(DeclarativeBase):
__table__ = service_catalog
#relation definitions
organization = relationship('Organization', primaryjoin='ServiceCatalog.organization_id==Organization.id')
activities = relationship('Activity', primaryjoin='ServiceCatalog.id==ActivityService.service_id', secondary=activity_service, secondaryjoin='ActivityService.activity_id==Activity.id')
service_catalog = relationship('ServiceCatalog', primaryjoin='ServiceCatalog.parent_service_id==ServiceCatalog.id')
organizations = relationship('Organization', primaryjoin='ServiceCatalog.id==ServiceCatalog.parent_service_id', secondary=service_catalog, secondaryjoin='ServiceCatalog.organization_id==Organization.id')
在ServiceCatalog.organizations中,它希望辅助表为service_catalog,但该变量只是在本地被覆盖。切换两者的顺序将解决这个问题。