我试图使用相关模型的DateTimeField
中的数据来注释对象
class Author(models.Model):
name = models.CharField(max_length=256)
class Book(models.Model):
name = models.CharField(max_length=256)
is_published = models.BooleanField()
publication_date = models.DateTimeField()
author = models.ForeignKey(Author, on_delete=models.PROTECT)
queryset = Author.objects.annotate(
has_unpublished=Exists(
Book.objects.filter(
author=OuterRef('pk'),
is_published=False))
).annotate(
last_published_date=Max(
'book__publication_date',
filter=Q(book__is_published=True)
)
)
我在默认的本地sqlite3
数据库和MySQL
(使用mysqlclient
)之间切换。SQLite工作,MySQL崩溃
原因是:两个数据库的编译器
results = compiler.execute_sql(**kwargs)
返回int和string元组列表,如下所示:
SQLite
<class 'list'>: [[(1, 'Alice', 1, '2017-01-01 01:00:00'), (2, 'Bob', 0, '2019-01-05 13:00:00'), (3, 'Carol', 1, None), (4, 'Dan', 0, None)]]
MySQL
<class 'list'>: [((1, 'Alice', 1, '2017-01-01 01:00:00.000000'), (2, 'Bob', 0, '2019-01-05 13:00:00.000000'), (3, 'Carol', 1, None), (4, 'Dan', 0, None))]
现在,当SQLite后端看到一个假定的datetime字段时,它会在运行时使用以下方法生成一个转换器:
django.db.backends.sqlite3.operations.DatabaseOperations
def convert_datetimefield_value(self, value, expression, connection):
if value is not None:
if not isinstance(value, datetime.datetime):
value = parse_datetime(value)
if settings.USE_TZ and not timezone.is_aware(value):
value = timezone.make_aware(value, self.connection.timezone)
return value
这样就行了
但是,MySQL后端执行以下操作:
django.db.backends.mysql.operations.DatabaseOperations
def convert_datetimefield_value(self, value, expression, connection):
if value is not None:
value = timezone.make_aware(value, self.connection.timezone)
return value
Django然后继续崩溃,试图检查<str>
的时区感知
上面是一个玩具的例子,我用来复制崩溃
在我们实际的生产环境中,MySQL编译器的execute_sql
,奇怪的是,如果我请求一个带注释作者的完整列表(action=='list'
),它会返回一个带有datetime.datetime
对象的“原始”数据元组列表,如果我请求一个特定的作者(action=='retrieve'
),它会返回一个带有字符串的相同列表。查询集各自的sql查询仅因存在单个WHERE子句而不同
这让我觉得我做错了什么,没有从驱动程序那里得到我应该得到的原始信息(而不是Django中出现错误的可能性要低得多)
我该怎么办?N+1是不可能的,这将是应用程序的主要操作员视图,datetime字段实际上是一对多关系
目前没有回答
相关问题 更多 >
编程相关推荐