django - 我不能将 Q 过滤器模型与 2 个相关数据库一起使用
django - I can't use the Q filter model with 2 related databases
我在 models.py 有以下 2 个与 2 个不同数据库相关的模型:
class AnalogicalValues(models.Model):
id = models.BigAutoField(primary_key=True)
date = models.DateField()
description = models.ForeignKey(ExpensesDescription, models.DO_NOTHING)
continent_id = models.ForeignKey(
'WorldContinent', db_column='continent_id', on_delete=models.DO_NOTHING
)
(...)hide code(...)
city_id = models.ForeignKey(
'WorldCity', db_column='city_id', verbose_name='City', on_delete=models.DO_NOTHING
)
value = models.FloatField()
comments = models.CharField(max_length=255, blank=True, null=True)
user_id = models.ForeignKey(User, db_column='user_id', on_delete=models.DO_NOTHING)
class Meta:
managed = False
db_table = 'analogical_values'
ordering = ('-date', '-id')
class WorldCity(models.Model):
id = models.AutoField(primary_key=True, unique=True)
name = models.CharField(max_length=255, verbose_name='City')
continent = models.ForeignKey(WorldContinent, models.DO_NOTHING)
country = models.ForeignKey(WorldCountry, models.DO_NOTHING)
subcountry = models.ForeignKey(WorldSubcountry, models.DO_NOTHING)
last_update_db = models.DateTimeField()
class Meta:
managed = False
db_table = 'cities'
ordering = ('name',)
verbose_name_plural = 'List of World Cities'
verbose_name = 'World City'
def __str__(self):
return self.name
它们之间的关系是来自 AnalogicalValues 的 city_id 和来自 WorldCity 的 id,每个模型都映射到 routers.py 上的相应数据库。 AnalogicalValues 上的描述字段是与 analogical_values 在同一数据库中的其他 table 的外键,并且工作正常。
class WorldRouter:
route_app_labels = {'myapp'}
route_model_list = {'WorldCity'}
def db_for_read(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'world_db'
return None
def db_for_write(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'world_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
class ExpensesRouter:
route_app_labels = {'myapp'}
route_model_list = {'AnalogicalValues'}
def db_for_read(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'expenses_db'
return None
def db_for_write(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'expenses_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
在 models.py 中,我想获得关于我在 'filterData' 表单上写的字符串的所有列的所有结果:
from . import models
from django.views import generic
class DataView(generic.ListView, generic.FormView):
(...some code...)
model = models.AnalogicalValues
paginate_by = 10
def get(self, *args, **kwargs):
(...some code...)
datalist = self.model.objects.filter(
Q(user_id__exact=self.request.user) &
(
Q(date__icontains=kwargs['filterData'])
| Q(description__name__icontains=kwargs['filterData'])
| Q(city_id__name__icontains=kwargs['filterData'])
| Q(value__icontains=kwargs['filterData'])
| Q(comments__icontains=kwargs['filterData'])
)
)
self.paginate_by = datalist.count()
(...some code...)
return render(self.request, self.template_name, {
'datalist': datalist,
(...some args...)
})
当 django 到达 self.paginate_by 行时,出现此错误
Environment:
Traceback (most recent call last):
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 73, in execute
return self.cursor.execute(query, args)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/cursors.py", line 206, in execute
res = self._query(query)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/cursors.py", line 319, in _query
db.query(q)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/connections.py", line 259, in query
_mysql.connection.query(self, query)
The above exception ((1146, "Table 'EXPENSES.cities' doesn't exist")) was the direct cause of the following exception:
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/BN_APP/myapp/views.py", line 43, in dispatch
return super(UserAccessMixin, self).dispatch(self.request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/contrib/auth/mixins.py", line 85, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/BN_APP/myapp/views.py", line 1256, in post
return FinancialDataView.get(self, **kwargs)
File "/home/bruno/Python/BN_APP/BN_APP/myapp/views.py", line 1158, in get
self.paginate_by = datalist.count()
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/models/query.py", line 411, in count
return self.query.get_count(using=self.db)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/models/sql/query.py", line 515, in get_count
number = obj.get_aggregation(using, ['__count'])['__count']
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/models/sql/query.py", line 500, in get_aggregation
result = compiler.execute_sql(SINGLE)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1156, in execute_sql
cursor.execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 73, in execute
return self.cursor.execute(query, args)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/cursors.py", line 206, in execute
res = self._query(query)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/cursors.py", line 319, in _query
db.query(q)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/connections.py", line 259, in query
_mysql.connection.query(self, query)
Exception Type: ProgrammingError at /financial_data/
Exception Value: (1146, "Table 'EXPENSES.cities' doesn't exist")
我进行了一些挖掘,并检查了它构建的查询是否遗漏了 table 个城市的数据库名称。谁能帮我解决这个问题?谢谢
(已编辑)
执行的查询:
USE EXPENSES;
SELECT
analogical_values.id
, analogical_values.date
, analogical_values.description_id
, analogical_values.transaction_type_id
, analogical_values.payment_method_id
, analogical_values.continent_id
, analogical_values.country_id
, analogical_values.subcountry_id
, analogical_values.city_id
, analogical_values.value
, analogical_values.comments
, analogical_values.user_id
, analogical_values.last_update_db
FROM
analogical_values
INNER JOIN
description
ON
(
analogical_values. description_id = description.description_id
)
INNER JOIN
transaction_type
ON
(
analogical_values.transaction_type_id = transaction_type.transaction_type_id
)
INNER JOIN
payment_method
ON
(
analogical_values.payment_method_id = payment_method.payment_method_id
)
INNER JOIN
countries
ON
(
analogical_values.country_id = countries.id
)
INNER JOIN
cities
ON
(
analogical_values.city_id = cities.id
)
WHERE
(
analogical_values.user_id = 2
AND
(
analogical_values.date LIKE '%test%'
OR description.name LIKE '%test%'
OR transaction_type.name LIKE '%test%'
OR payment_method.name LIKE '%test%'
OR countries.name LIKE '%test%'
OR cities.name LIKE '%test%'
OR analogical_values.value LIKE '%test%'
OR analogical_values.comments LIKE '%test%'
)
)
ORDER BY
analogical_values.date DESC, analogical_values.id DESC
在最后 2 个 INNER JOINS 中,tables 属于 WORLD 数据库,例如 WORLD.countries 和 WORLD.cities
Exception Value: (1146, "Table 'EXPENSES.cities' doesn't exist")
如果您阅读异常,很容易看出 table 不存在。
可能先进行迁移。
我知道这不是最佳做法,但我直接从模型中做了一个过滤器,并为 Q 过滤器获取了所有 ID,它起作用了
if kwargs['filterData']:
city_list = models.WorldCity.objects.filter(name__icontains=kwargs['filterData']).values()
city_id = []
[city_id.append(cur_city.get('id')) for cur_city in city_list]
else:
city_id = models.WorldCity.objects.none()
datalist = self.model.objects.filter(
Q(user_id__exact=self.request.user) &
(
Q(date__icontains=kwargs['filterData'])
| Q(description__name__icontains=kwargs['filterData'])
| Q(city_id__id__in=city_id)
| Q(value__icontains=kwargs['filterData'])
| Q(comments__icontains=kwargs['filterData'])
)
)
self.paginate_by = datalist.count()
我在 models.py 有以下 2 个与 2 个不同数据库相关的模型:
class AnalogicalValues(models.Model):
id = models.BigAutoField(primary_key=True)
date = models.DateField()
description = models.ForeignKey(ExpensesDescription, models.DO_NOTHING)
continent_id = models.ForeignKey(
'WorldContinent', db_column='continent_id', on_delete=models.DO_NOTHING
)
(...)hide code(...)
city_id = models.ForeignKey(
'WorldCity', db_column='city_id', verbose_name='City', on_delete=models.DO_NOTHING
)
value = models.FloatField()
comments = models.CharField(max_length=255, blank=True, null=True)
user_id = models.ForeignKey(User, db_column='user_id', on_delete=models.DO_NOTHING)
class Meta:
managed = False
db_table = 'analogical_values'
ordering = ('-date', '-id')
class WorldCity(models.Model):
id = models.AutoField(primary_key=True, unique=True)
name = models.CharField(max_length=255, verbose_name='City')
continent = models.ForeignKey(WorldContinent, models.DO_NOTHING)
country = models.ForeignKey(WorldCountry, models.DO_NOTHING)
subcountry = models.ForeignKey(WorldSubcountry, models.DO_NOTHING)
last_update_db = models.DateTimeField()
class Meta:
managed = False
db_table = 'cities'
ordering = ('name',)
verbose_name_plural = 'List of World Cities'
verbose_name = 'World City'
def __str__(self):
return self.name
它们之间的关系是来自 AnalogicalValues 的 city_id 和来自 WorldCity 的 id,每个模型都映射到 routers.py 上的相应数据库。 AnalogicalValues 上的描述字段是与 analogical_values 在同一数据库中的其他 table 的外键,并且工作正常。
class WorldRouter:
route_app_labels = {'myapp'}
route_model_list = {'WorldCity'}
def db_for_read(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'world_db'
return None
def db_for_write(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'world_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
class ExpensesRouter:
route_app_labels = {'myapp'}
route_model_list = {'AnalogicalValues'}
def db_for_read(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'expenses_db'
return None
def db_for_write(self, model, **hints):
if (
model._meta.app_label in self.route_app_labels and
model._meta.object_name in self.route_model_list
):
return 'expenses_db'
return None
def allow_relation(self, obj1, obj2, **hints):
if (
obj1._meta.app_label in self.route_app_labels or
obj2._meta.app_label in self.route_app_labels
):
return True
return None
在 models.py 中,我想获得关于我在 'filterData' 表单上写的字符串的所有列的所有结果:
from . import models
from django.views import generic
class DataView(generic.ListView, generic.FormView):
(...some code...)
model = models.AnalogicalValues
paginate_by = 10
def get(self, *args, **kwargs):
(...some code...)
datalist = self.model.objects.filter(
Q(user_id__exact=self.request.user) &
(
Q(date__icontains=kwargs['filterData'])
| Q(description__name__icontains=kwargs['filterData'])
| Q(city_id__name__icontains=kwargs['filterData'])
| Q(value__icontains=kwargs['filterData'])
| Q(comments__icontains=kwargs['filterData'])
)
)
self.paginate_by = datalist.count()
(...some code...)
return render(self.request, self.template_name, {
'datalist': datalist,
(...some args...)
})
当 django 到达 self.paginate_by 行时,出现此错误
Environment:
Traceback (most recent call last):
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 73, in execute
return self.cursor.execute(query, args)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/cursors.py", line 206, in execute
res = self._query(query)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/cursors.py", line 319, in _query
db.query(q)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/connections.py", line 259, in query
_mysql.connection.query(self, query)
The above exception ((1146, "Table 'EXPENSES.cities' doesn't exist")) was the direct cause of the following exception:
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/contrib/auth/mixins.py", line 52, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/BN_APP/myapp/views.py", line 43, in dispatch
return super(UserAccessMixin, self).dispatch(self.request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/contrib/auth/mixins.py", line 85, in dispatch
return super().dispatch(request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "/home/bruno/Python/BN_APP/BN_APP/myapp/views.py", line 1256, in post
return FinancialDataView.get(self, **kwargs)
File "/home/bruno/Python/BN_APP/BN_APP/myapp/views.py", line 1158, in get
self.paginate_by = datalist.count()
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/models/query.py", line 411, in count
return self.query.get_count(using=self.db)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/models/sql/query.py", line 515, in get_count
number = obj.get_aggregation(using, ['__count'])['__count']
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/models/sql/query.py", line 500, in get_aggregation
result = compiler.execute_sql(SINGLE)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1156, in execute_sql
cursor.execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 98, in execute
return super().execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/django/db/backends/mysql/base.py", line 73, in execute
return self.cursor.execute(query, args)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/cursors.py", line 206, in execute
res = self._query(query)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/cursors.py", line 319, in _query
db.query(q)
File "/home/bruno/Python/BN_APP/venv/lib/python3.8/site-packages/MySQLdb/connections.py", line 259, in query
_mysql.connection.query(self, query)
Exception Type: ProgrammingError at /financial_data/
Exception Value: (1146, "Table 'EXPENSES.cities' doesn't exist")
我进行了一些挖掘,并检查了它构建的查询是否遗漏了 table 个城市的数据库名称。谁能帮我解决这个问题?谢谢
(已编辑)
执行的查询:
USE EXPENSES;
SELECT
analogical_values.id
, analogical_values.date
, analogical_values.description_id
, analogical_values.transaction_type_id
, analogical_values.payment_method_id
, analogical_values.continent_id
, analogical_values.country_id
, analogical_values.subcountry_id
, analogical_values.city_id
, analogical_values.value
, analogical_values.comments
, analogical_values.user_id
, analogical_values.last_update_db
FROM
analogical_values
INNER JOIN
description
ON
(
analogical_values. description_id = description.description_id
)
INNER JOIN
transaction_type
ON
(
analogical_values.transaction_type_id = transaction_type.transaction_type_id
)
INNER JOIN
payment_method
ON
(
analogical_values.payment_method_id = payment_method.payment_method_id
)
INNER JOIN
countries
ON
(
analogical_values.country_id = countries.id
)
INNER JOIN
cities
ON
(
analogical_values.city_id = cities.id
)
WHERE
(
analogical_values.user_id = 2
AND
(
analogical_values.date LIKE '%test%'
OR description.name LIKE '%test%'
OR transaction_type.name LIKE '%test%'
OR payment_method.name LIKE '%test%'
OR countries.name LIKE '%test%'
OR cities.name LIKE '%test%'
OR analogical_values.value LIKE '%test%'
OR analogical_values.comments LIKE '%test%'
)
)
ORDER BY
analogical_values.date DESC, analogical_values.id DESC
在最后 2 个 INNER JOINS 中,tables 属于 WORLD 数据库,例如 WORLD.countries 和 WORLD.cities
Exception Value: (1146, "Table 'EXPENSES.cities' doesn't exist")
如果您阅读异常,很容易看出 table 不存在。 可能先进行迁移。
我知道这不是最佳做法,但我直接从模型中做了一个过滤器,并为 Q 过滤器获取了所有 ID,它起作用了
if kwargs['filterData']:
city_list = models.WorldCity.objects.filter(name__icontains=kwargs['filterData']).values()
city_id = []
[city_id.append(cur_city.get('id')) for cur_city in city_list]
else:
city_id = models.WorldCity.objects.none()
datalist = self.model.objects.filter(
Q(user_id__exact=self.request.user) &
(
Q(date__icontains=kwargs['filterData'])
| Q(description__name__icontains=kwargs['filterData'])
| Q(city_id__id__in=city_id)
| Q(value__icontains=kwargs['filterData'])
| Q(comments__icontains=kwargs['filterData'])
)
)
self.paginate_by = datalist.count()