我在Django环境中使用SQLAlchemy(v1.2.11),因此我可以在Firebird数据库(由该公司的ERP使用)与我在Django中开发的Intranet之间进行一些映射。我将 declarative_base 用于映射,因为自省不起作用。
其中一个限制是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中删除属性 seller ,并更改我的查询:
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 and Products的关系是完全相同的,带有复合外键,并且很好用。因此,组合键或Firebird数据库似乎不是问题。
设置断点时,我可以看到当SQLAlchemy是Mapper类中的ForeignKeys(sqlalchemy / orm)时,它们不会将 seller_id 和 seller_company 识别为已声明的字段。 /mapper.py)。
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'
答案 0 :(得分:2)
这有点打错字,但有时会弹出。错误消息告诉您确切的问题所在:
seller_id = (Integer, ForeignKey('sellers.seller_id'))
创建一个元组,而不是Column
。你是说
seller_id = Column(Integer, ForeignKey('sellers.seller_id'))
seller_company
中有相同的错字。