背景情况说明:
我正在创建一个使用 Microsoft SQL Server 作为后端数据库的 Django2 应用程序。SQL_VARIANT
该数据库有几个包含字段的表(我无法管理或更改它们) 。此字段包含空字符串或数字(它们用作主键或外键)
问题:
在 MSSQL 上,当您JOIN
使用一个SQL_VARIANT
字段和一个VARCHAR
字段时,它会产生一个空行结果,要解决这个问题,您必须使用显式将 SQL_VARIANT 字段转换为 VARCHARCAST([Table Name].[SQL_VARIANT Field Name] AS VARCHAR
目标:
我想找到一种方法,CAST([Table Name].[SQL_VARIANT Field Name] AS VARCHAR
每次 DjangoJOIN
在 QuerySet 上创建或调用 QuerySetSQL_VARIANT
上的字段时
我怎样才能做到这一点?
代码作为参考:
在我的问题中,我使用了 MSSQL 数据库中的 3 个表(供应商、产品和产品分类帐条目)
供应商表
create table [Vendor]
(
Id sql_variant not null primary key,
Name varchar(30) not null,
Address varchar(30) not null,
City varchar(30) not null,
Contact varchar(30) not null,
Type int not null,
Category int not null,
)
产品表
create table [Product]
(
Id varchar(20) not null primary key,
Description varchar(60) not null,
Class varchar(10) not null,
[Vendor Id] varchar(20) not null,
)
产品分类帐条目表
create table [Product Ledger Entry]
(
Id int not null primary key,
[Product Id] varchar(20) not null,
[Posting Date] datetime not null,
[Entry Type] int not null,
[Source Id] varchar(20) not null,
[Document Id] varchar(20) not null,
Quantity decimal(38,20) not null,
)
如果我想横穿所有 3 张桌子,我会做......
SELECT
[Vendor].[Id],
[Vendor].[Name],
[Product].[Id],
[Product Ledger Entry].Quantity
FROM [Vendor]
INNER JOIN [Product] ON ([Vendor].[Id] = [Product].[Vendor Id])
INNER JOIN [Product Ledger Entry] ON ([Product].[Id] = [Product Ledger Entry].[Product Id])
但是,此查询不会产生任何行。只有通过对SQL_VARIANT
字段进行显式强制转换,此查询才会显示异常结果。
SELECT
[Vendor].[Id],
[Vendor].[Name],
[Product].[Id],
[Product Ledger Entry].Quantity
FROM [Vendor]
INNER JOIN [Product] ON (CAST([Vendor].[Id] AS VARCHAR(20)) = [Product].[Vendor Id])
INNER JOIN [Product Ledger Entry] ON ([Product].[Id] = [Product Ledger Entry].[Product Id])
当你使用 Django 时也会发生同样的事情,这里是模型:
class Vendor(models.Model):
id = models.CharField(db_column='Id', primary_key=True, , max_length=20)
name = models.CharField(db_column='Name', max_length=30)
# Address Description
address = models.CharField(db_column='Address', max_length=30)
# Province/City/Municipality
city = models.CharField(db_column='City', max_length=30)
class Meta:
managed = False
db_table = 'Vendor'
def __str__(self):
return f'{self.id} | {self.name}'
class Product(models.Model):
id = models.CharField(db_column='No_', primary_key=True, max_length=20)
description = models.CharField(db_column='Description', max_length=60)
vendor_id = models.ForeignKey(
'Vendor', on_delete=models.CASCADE,
db_column='Vendor Id', to_field='id', related_name='products', db_index=False, blank=True
)
class Meta:
managed = False
db_table = 'Product'
def __str__(self):
return f'{self.id}'
class ProductLedgerEntry(models.Model):
id = models.IntegerField(db_column='Id', primary_key=True)
product_id = models.ForeignKey(
'Product', on_delete=models.CASCADE,
db_column='Product Id', to_field='id', related_name='ledger_entries', db_index=False
)
posting_date = models.DateTimeField(db_column='Posting Date')
ENTRY_TYPE = [
(0, 'Compra'),
(1, 'Venta'),
(2, 'Ajuste positivo'),
(3, 'Ajuste negativo'),
(4, 'Transferencia'),
(5, 'Consumo'),
(6, 'Salida desde fab.'),
]
entry_type = models.IntegerField(
db_column='Entry Type', choices=ENTRY_TYPE
)
quantity = models.DecimalField(db_column='Quantity', max_digits=38, decimal_places=20)
class Meta:
managed = False
db_table = 'Product Ledger Entry'
def __str__(self):
return f'{self.product_id} | {self.variant_code} | {self.posting_date}'
只要我不使用 annotate(...)、select_related(...) 或任何其他 Django API 方法JOIN
,我就可以设法获得正确的结果。但是,我想使用注释。
请帮我