Python 3.6
Django 2.2.3
Mariadb
I am developing a web program using Django that displays various statistics.
Created "models.py" by "inspectdb" from an existing MariaDB database.
I'm trying to use "Raw" queries because of mixed queries from many tables
However, the following error occurs.
django.db.models.query_utils.InvalidQuery: Raw query must include the primary key
Mariadb tables
# table : user
uid(int(10), primary, auto_increment)
email(varchar(100))
created_at(timestamp)
# table : user_logs
seq(int(11), primary, auto_increment)
uid(int(10))
acct_type(tinyint(2))
log_type(varchar(20))
created_at(timestamp)
#query
SELECT
years,
months,
sum(download) AS download,
sum(countin) AS user_regist,
sum(countout) AS user_login
FROM (
SELECT
YEAR(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS years,
MONTH(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS months,
count(1) AS `countin`,0 AS `countout`, 0 AS 'download'
FROM user `in`
WHERE (
DATE_ADD(created_at, INTERVAL 9 HOUR) >= '2019-09-01 00:00:00' AND
DATE_ADD(created_at, INTERVAL 9 HOUR) < '2020-01-20 00:00:00')
GROUP BY `years`, `months`
UNION
SELECT
YEAR(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS years,
MONTH(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS months,
0 `countin`,
count(1) AS `countout`,
0 AS 'download'
FROM user_logs `out`
WHERE (
acct_type = 1 AND
log_type = 'login' AND
DATE_ADD(created_at, INTERVAL 9 HOUR) >= '2019-09-01 00:00:00' AND
DATE_ADD(created_at, INTERVAL 9 HOUR) < '2020-01-20 00:00:00')
GROUP BY `years`, `months`
) `regist_and_login_monthly`
GROUP BY years, months;
query resulit
models.py
class User(models.Model):
uid = models.AutoField(primary_key=True)
email = models.CharField(max_length=100, blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
class Meta:
managed = False
db_table = 'user'
ordering = ['-created_at']
class UserLogs(models.Model):
seq = models.AutoField(primary_key=True)
uid = models.PositiveIntegerField(primary_key=True)
acct_type = models.IntegerField(blank=True, null=True)
log_type = models.CharField(max_length=20, blank=True, null=True)
created_at = models.DateTimeField(blank=True, null=True)
class Meta:
managed = False
db_table = 'user_logs'
ordering = ['-created_at']
views.py
# same as query
user_monthly_status = User.objects.raw(
'''
SELECT
years,
months,
sum(download) AS download,
sum(countin) AS user_regist,
sum(countout) AS user_login
FROM (
SELECT
YEAR(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS years,
MONTH(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS months,
count(1) AS `countin`,0 AS `countout`, 0 AS 'download'
FROM user `in`
WHERE (
DATE_ADD(created_at, INTERVAL 9 HOUR) >= '2019-09-01 00:00:00' AND
DATE_ADD(created_at, INTERVAL 9 HOUR) < '2020-01-20 00:00:00')
GROUP BY `years`, `months`
UNION
SELECT
YEAR(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS years,
MONTH(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS months,
0 `countin`,
count(1) AS `countout`,
0 AS 'download'
FROM user_logs `out`
WHERE (
acct_type = 1 AND
log_type = 'login' AND
DATE_ADD(created_at, INTERVAL 9 HOUR) >= '2019-09-01 00:00:00' AND
DATE_ADD(created_at, INTERVAL 9 HOUR) < '2020-01-20 00:00:00')
GROUP BY `years`, `months`
) `regist_and_login_monthly`
GROUP BY years, months;
'''
)
When I searched for this error, people says put '1 as id' or 'each table's primary colunm' in each 'Select', but the same error occurred.
What should I do?
As soon as I fill out the question, I solve it and share the result.
hint from https://docs.djangoproject.com/en/2.2/topics/db/sql/#deferring-model-fields
I added a 'PK column' of 'table' to each 'Select' and put one of them into first 'Select'.
user_monthly_status = User.objects.raw(
'''
SELECT
uid, # add !!!!!!!
years,
months,
sum(download) AS download,
sum(countin) AS user_regist,
sum(countout) AS user_login
FROM (
SELECT
uid,# add !!!!!!!
YEAR(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS years,
MONTH(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS months,
count(1) AS `countin`,0 AS `countout`, 0 AS 'download'
FROM user `in`
WHERE (
DATE_ADD(created_at, INTERVAL 9 HOUR) >= '2019-09-01 00:00:00' AND
DATE_ADD(created_at, INTERVAL 9 HOUR) < '2020-01-20 00:00:00')
GROUP BY `years`, `months`
UNION
SELECT
seq,# add !!!!!!!!
YEAR(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS years,
MONTH(DATE_ADD(created_at, INTERVAL 9 HOUR)) AS months,
0 `countin`,
count(1) AS `countout`,
0 AS 'download'
FROM user_logs `out`
WHERE (
acct_type = 1 AND
log_type = 'login' AND
DATE_ADD(created_at, INTERVAL 9 HOUR) >= '2019-09-01 00:00:00' AND
DATE_ADD(created_at, INTERVAL 9 HOUR) < '2020-01-20 00:00:00')
GROUP BY `years`, `months`
) `regist_and_login_monthly`
GROUP BY years, months;
'''
)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.