3

我在为旧版 MSSQL 数据库实施 SQLalchemy 时遇到了很多麻烦。这是一个很大的现有数据库,所以我想使用sqlautocode为我生成文件,因为使用自动加载来反映数据库需要太长时间。

第一个问题是 sqlautocode 似乎不再适用于 SQLalchemy 0.8。我确实仍然有早期版本的现有输出,所以我想我会使用它,只是为了测试。

现在 sqlautocode 输出“经典映射”,这并不是真正的问题,但是每当我尝试使用外键时,'RelationshipProperty' object has no attribute 'c'都会出现。SQLalchemy 库深处的某个错误。

所以接下来,我尝试跳过 sqlautocode 并自己编写类和关系,使用 SQLalchemy 0.8 的这段代码。我使用了两个示例表,我得到了完全相同的错误。然后我注释掉了大部分列,所有的关系,我 - 仍然 - 得到错误。

下面是我的代码:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.dialects.mssql import *

Base = declarative_base()


class PeopleMemberhip(Base):
    __tablename__ = 'people_memberships'

    ppl_mshp_id = Column(VARCHAR(length=36), primary_key=True, nullable=False)
    ppl_mshp_startdate = Column(DATETIME())
    ppl_mshp_enddate = Column(DATETIME())
    # ppl_mshp_pmsd_id = Column(VARCHAR(length=36), ForeignKey('paymentschedules.pmsd_id'))

    # paymentschedule = relationship("PaymentSchedule", backref=backref('people_memberships'))

    def __repr__(self):
        return "<people_membership('%s','%s')>" % (self.ppl_mshp_id, self.ppl_mshp_startdate)


class PaymentSchedule(Base):
    __tablename__ = 'paymentschedules'

    pmsd_id = Column(VARCHAR(length=36), primary_key=True, nullable=False)
    pmsd_name = Column(NVARCHAR(length=60))
    pmsd_startdate = Column(DATETIME())
    pmsd_enddate = Column(DATETIME())

    # paymentschedule = relationship("PaymentSchedule", backref=backref('people_memberships'))

    def __repr__(self):
        return "<paymentschedule('%s','%s')>" % (self.pmsd_id, self.pmsd_name)

以及由此产生的错误:

Traceback (most recent call last):
  File "C:\Program Files (x86)\JetBrains\PyCharm 2.7\helpers\pydev\pydevd.py", line 1472, in <module>
    debugger.run(setup['file'], None, None)
  File "C:\Program Files (x86)\JetBrains\PyCharm 2.7\helpers\pydev\pydevd.py", line 1116, in run
    pydev_imports.execfile(file, globals, locals) #execute the script
  File "C:/Users/erik/workspace/flasktest/test.py", line 16, in <module>
    contract = db.session.query(PeopleMemberhip).filter_by(ppl_mshp_id='98ABD7E9-4CFF-4F7B-8537-8E46FD5C79D5').one()
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\scoping.py", line 149, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\session.py", line 1105, in query
    return self._query_cls(entities, self, **kwargs)
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\query.py", line 115, in __init__
    self._set_entities(entities)
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\query.py", line 124, in _set_entities
    self._set_entity_selectables(self._entities)
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\query.py", line 157, in _set_entity_selectables
    ent.setup_entity(*d[entity])
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\query.py", line 2744, in setup_entity
    self._with_polymorphic = ext_info.with_polymorphic_mappers
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\util\langhelpers.py", line 582, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\mapper.py", line 1425, in _with_polymorphic_mappers
    configure_mappers()
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\mapper.py", line 2106, in configure_mappers
    mapper._post_configure_properties()
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\mapper.py", line 1242, in _post_configure_properties
    prop.init()
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\interfaces.py", line 231, in init
    self.do_init()
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\properties.py", line 1028, in do_init
    self._setup_join_conditions()
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\properties.py", line 1102, in _setup_join_conditions
    can_be_synced_fn=self._columns_are_mapped
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\relationships.py", line 115, in __init__
    self._annotate_fks()
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\relationships.py", line 311, in _annotate_fks
    self._annotate_present_fks()
  File "C:\Users\erik\workspace\flasktest\lib\site-packages\sqlalchemy\orm\relationships.py", line 331, in _annotate_present_fks
    secondarycols = util.column_set(self.secondary.c)
AttributeError: 'RelationshipProperty' object has no attribute 'c'

我真的很茫然,感谢任何有关此错误的帮助,但如果有人可以提出一种不同的方法,可以使 SQLalchemy 与我们的旧版 MSSQL 数据库一起工作,它也是一个解决方案。

正如我所说,sqlautocode 似乎不再工作了,但也许我使用它的方式错误,或者可能有一个我不知道的替代工具。

埃里克

4

1 回答 1

2

好吧,伙计们,我自己想通了。

我有几个我正在处理的文件,其中包含表定义(来自 sqlautocode 的输出)。一个被称为“database.py”,另一个被称为“model.py”,最后一个被称为“ORM.py”。

我有一个导入“model.py”的 test.py 文件。Model.py 是我在其中编写表定义的文件。但是 - test.py 页面也在从 Flask ( from app import app, db) 中导入数据库,并且在__init__()Flask 应用程序的功能中,Flask 仍在加载“ORM.py” .

所以一些对象来自 ORM.py,这是一个由 sqlautocode 生成的旧文件,而不是来自我正在试验的 model.py。

重命名 ORM.py 给了我一个线索。我用 Python 编写了一个非常简单的脚本,它遍历 MSSQL 表和列并为我生成一个 model.py。我现在专门加载该 model.py 文件,并且整个工作正常!

抱歉,如果有人花时间在这上面。希望它可以帮助有人用谷歌搜索同样的问题。

埃里克

于 2013-03-27T14:43:59.950 回答