Skip to content

Commit e4883e5

Browse files
committed
adopt project to be used with Postgres
adopt project to be used with Postgres
1 parent 0e1c204 commit e4883e5

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

finder/models/inode.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,33 @@
33

44
from django.conf import settings
55
from django.core.exceptions import ImproperlyConfigured, ValidationError
6-
from django.db import models
6+
from django.db import connections, models
77
from django.db.models.aggregates import Aggregate
88
from django.db.models.expressions import F, Value
99
from django.db.models.fields import BooleanField, CharField
10-
from django.db.models.functions import Lower
10+
from django.db.models.functions import Cast, Lower
1111
from django.utils.functional import cached_property
1212
from django.utils.translation import gettext_lazy as _
1313

14+
try:
15+
from django.contrib.postgres.aggregates import StringAgg
16+
except ImportError: # psycopg2 is not installed
17+
pass
18+
1419

1520
class GroupConcat(Aggregate):
21+
"""
22+
To be used on SQLite, MySQL and MariaDB databases. For Postgres, use `StringAgg`.
23+
"""
1624
function = 'GROUP_CONCAT'
1725
template = '%(function)s(%(distinct)s %(expressions)s)'
18-
# template = '%(function)s(%(distinct)s %(expressions)s%(separator)s)'
1926
allow_distinct = True
2027

21-
def __init__(self, expression, distinct=False, ordering=None, separator=',', output_field=None, **extra):
28+
def __init__(self, expression, distinct=False, ordering=None, output_field=None, **extra):
2229
super().__init__(
2330
expression,
2431
distinct='DISTINCT ' if distinct else '',
2532
ordering=f' ORDER BY {ordering}' if ordering is not None else '',
26-
separator=f",'{separator}'",
2733
output_field=CharField() if output_field is None else output_field,
2834
**extra
2935
)
@@ -97,15 +103,21 @@ def get_queryset(model):
97103
is_folder=Value(model.is_folder, output_field=BooleanField()),
98104
**unified_annotations,
99105
)
100-
expressions = {'label_ids':
101-
Value(None, output_field=CharField()) if model.is_folder
102-
else GroupConcat('labels__id', distinct=True)
103-
}
106+
if model.is_folder:
107+
expressions = {'label_ids': Value('', output_field=CharField())}
108+
else:
109+
vendor = connections[model.objects.db].vendor
110+
if vendor == 'postgresql':
111+
concatenated = Cast('labels__id', output_field=CharField())
112+
expressions = {'label_ids': StringAgg(concatenated, ',', distinct=True)}
113+
else:
114+
expressions = {'label_ids': GroupConcat('labels__id', distinct=True)}
104115
for name, field in unified_fields.items():
105116
if name in annotations:
106117
concrete_fields.remove(name)
107118
elif name not in model_field_names:
108-
expressions[name] = Value(None, output_field=field)
119+
value = None if field.default is models.NOT_PROVIDED else field.default
120+
expressions[name] = Value(value, output_field=field)
109121
queryset = model.objects.values(*concrete_fields, **expressions).annotate(**annotations)
110122
model_lookup = dict(lookup)
111123
labels = model_lookup.pop('labels__in', None)

testapp/settings.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,16 @@
8484
'default': {
8585
'ENGINE': 'django.db.backends.sqlite3',
8686
'NAME': BASE_DIR / 'workdir/db.sqlite3',
87-
}
87+
},
88+
'default_': {
89+
'ENGINE': 'django.db.backends.postgresql',
90+
'NAME': 'finder',
91+
'USER': 'finder',
92+
'PASSWORD': '',
93+
'HOST': 'localhost',
94+
'PORT': 5432,
95+
# 'CONN_MAX_AGE': 900,
96+
},
8897
}
8998

9099

0 commit comments

Comments
 (0)