类在SQLalchemy中没有名为“x”的映射列

问题描述 投票:1回答:1

我在Django环境中使用SQLAlchemy(v1.2.11),因此我可以在Firebird数据库(由公司的ERP使用)和我在Django中开发的内部网之间进行一些映射。我正在使用declarative_base作为映射,因为instrospection不起作用。

其中一个限制是Firebird本身(版本1.5),它没有多大帮助,而且我也无法触及数据库,只执行SELECT查询。

我想做的一件事是让用户在某些特定情况下创建报告并与Firebird数据交互,在我的Django项目中创建相关记录。

但是,在一个特定的映射中,我得到了

Class <class 'SalesDetail'> does not have a mapped column named 'seller_id'

准备查询并使用关系时。令我疯狂的是,我还在这个类ProductSells中映射了另外两个关系,它们非常相似,并且它们工作正常。

首先,我的基本映射,与我正在尝试查询的表(SalesDetail)相关:

class Sellers(Base):
    __tablename__ = 'sellers'

    seller_id = Column('seller_id', Integer)
    company_id = Column('company_id', Integer)
    name = Column('name', String)

    __mapper_args__ = {
        'primary_key': [seller_id, company_id],
    }


class Products(Base):
    __tablename__ = 'products'

    product_code = Column('product_code', Integer)
    company_id = Column('company_id', Integer)
    name = Column('name', String)
    product_type = Column('product_type', String)
    product_brand = Column(Integer, ForeignKey('brands.brand'))
    brand_company = Column(Integer, ForeignKey('brands.company_id'))
    status = Column('status', String)

    brand = relationship(
        'Brands',
        primaryjoin=(
            'and_('
            'Products.product_brand == Brands.brand, '
            'Products.brand_company == Brands.company_id'
            ')'
        ),
        innerjoin=True
    )

    __mapper_args__ = {
        'primary_key': [product_code, company_id],
    }


class Sales(Base):
    __tablename__ = 'sales'

    sale_id = Column('sale_id', Integer)
    company_id = Column(Integer, ForeignKey('clients.company_id'))
    sale_number = Column('sale_number', Integer)
    client_id = Column(Integer, ForeignKey('clients.client_id'))
    sale_date = Column('sale_date', Date)
    status = Column('status', String)

    client = relationship(
        'Clients',
        primaryjoin=(
            'and_('
            'Sales.client_id == Clients.client_id, '
            'Sales.company_id == Clients.company_id'
            ')'
        ),
        innerjoin=True
    )

    __mapper_args__ = {
        'primary_key': [sale_id, company_id],
    }

这是我想要查询的关系:

class SalesDetail(Base):
    __tablename__ = 'sales_detail'

    sale_id = Column(Integer, ForeignKey('sales.sale_id'))
    sale_company = Column(Integer, ForeignKey('sales.company_id'))
    sale_control = Column('sale_control', Integer)
    product_code = Column(Integer, ForeignKey('products.product_code'))
    product_company = Column(Integer, ForeignKey('products.company_id'))
    seller_id = (Integer, ForeignKey('sellers.seller_id'))
    seller_company = (Integer, ForeignKey('sellers.company_id'))
    qty = Column('qty', Integer)
    discount = Column('discount', Numeric)

    seller = relationship(
        'Sellers',
        primaryjoin=(
            'and_('
            'SalesDetail.seller_id == Sellers.seller_id, '
            'SalesDetail.seller_company == Sellers.company_id'
            ')'
        ),
        innerjoin=True
    )

    product = relationship(
        'Products',
        primaryjoin=(
            'and_('
            'SalesDetail.product_code == Products.product_code, '
            'SalesDetail.product_company == Products.company_id'
            ')'
        ),
        innerjoin=True
    )

    sale = relationship(
        'Sales',
        primaryjoin=(
            'and_('
            'SalesDetail.sale_id == Sales.sale_id, '
            'SalesDetail.sale_company == Sales.company_id'
            ')'
        ),
        innerjoin=True
    )

    __mapper_args__ = {
        'primary_key': [sale_id, sale_company, sale_control],
    }

我的查询是:

query = self.session.query(
            SalesDetail.sale_id,
            Sales.sale_date,
            Sellers.seller_id,
            Products.product_code,
            Products.name,
            SalesDetail.qty,
        ).join(
            SalesDetail.sale,
            SalesDetail.product,
            SalesDetail.seller,
            Products.brand
        )

        query = query.filter(and_(
            Sales.sale_date >= start_date,
            Sales.sale_date <= end_date,
            Sales.status != 'CAN',
            Sales.company_id == self.company.id,
            Products.product_type == 'R',
            Brands.name.in_(brands),
            Sellers.seller_id > 1001,
            Sellers.seller_id < 9000
        )).order_by(
            Sellers.seller_id,
            Sales.sale_date,
            Sales.sale_control
        )

        res = query.all()

这引发了一个例外:

Class <class 'src.erp.models.SalesDetail'> does not have a mapped column named 'seller_id'

但是,如果我将SalesDetail更改为:

class SalesDetail(Base):
    __tablename__ = 'sales_detail'

    sale_id = Column(Integer, ForeignKey('sales.sale_id'))
    sale_company = Column(Integer, ForeignKey('sales.company_id'))
    sale_control = Column('sale_control', Integer)
    product_code = Column(Integer, ForeignKey('products.product_code'))
    product_company = Column(Integer, ForeignKey('products.company_id'))
    seller_id = Column('seller_id', Integer)
    seller_company = ('company_id', Integer)
    qty = Column('qty', Integer)
    discount = Column('discount', Numeric)

如果我从SalesDetail中删除属性卖方,并更改我的查询:

query = self.session.query(
            SalesDetail.sale_id,
            Sales.sale_date,
            SalesDetail.seller_id,
            Products.product_code,
            Products.name,
            SalesDetail.qty,
        ).join(
            SalesDetail.sale,
            SalesDetail.product,
            Products.brand
        )

一切正常。有趣的是:我认为从SalesDetail到Sales和Products的关系完全相同,使用复合外键,它运行得很好。所以复合键或我的Firebird数据库似乎不是问题。

当我设置断点时,我可以看到,当它们是Mapper类中的ForeignKeys(sqlalchemy / orm / mapper.py)时,SQLAlchemy不会将seller_id和seller_company识别为声明的字段。

SQLAlchemy代码中的堆栈跟踪是这样的:

File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 2136, in join
    from_joinpoint=from_joinpoint)
File "<string>", line 2, in _join
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/base.py", line 201, in generate
    fn(self, *args[1:], **kw)
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 2243, in _join
    right_entity = onclause.property.mapper
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/util/langhelpers.py", line 767, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/attributes.py", line 215, in property
    return self.comparator.property
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/util/langhelpers.py", line 767, in __get__
    obj.__dict__[self.__name__] = result = self.fget(obj)
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/relationships.py", line 1354, in property
    mapperlib.Mapper._configure_all()
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/mapper.py", line 1276, in _configure_all
    configure_mappers()
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/mapper.py", line 3033, in configure_mappers
    mapper._post_configure_properties()
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/mapper.py", line 1832, in _post_configure_properties
    prop.init()
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/interfaces.py", line 183, in init
    self.do_init()
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/relationships.py", line 1655, in do_init
    self._process_dependent_arguments()
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/orm/relationships.py", line 1680, in _process_dependent_arguments
    setattr(self, attr, attr_value())
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/ext/declarative/clsregistry.py", line 281, in __call__
    x = eval(self.arg, globals(), self._dict)
File "<string>", line 1, in <module>
File "/home/alexandre/.virtualenvs/intranet-salao/lib/python3.5/site-packages/sqlalchemy/ext/declarative/clsregistry.py", line 213, in __getattr__
    % (self.cls, key))
sqlalchemy.exc.InvalidRequestError: Class <class 'src.erp.models.SalesDetail'> does not have a mapped column named 'seller_id'
python sqlalchemy
1个回答
2
投票

这有点像一个错字,但偶尔出现的东西。错误消息告诉您确切的错误:

seller_id = (Integer, ForeignKey('sellers.seller_id'))

创造一个元组,而不是Column。你的意思是

seller_id = Column(Integer, ForeignKey('sellers.seller_id'))

同样的拼写错误在seller_company

© www.soinside.com 2019 - 2024. All rights reserved.