Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
e585c43b
Kaydet (Commit)
e585c43b
authored
Eki 13, 2016
tarafından
Mads Jensen
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #25809 -- Added BrinIndex support in django.contrib.postgres.
Thanks Tim Graham and Markus Holtermann for review.
üst
236ebe94
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
121 additions
and
14 deletions
+121
-14
AUTHORS
AUTHORS
+1
-0
indexes.py
django/contrib/postgres/indexes.py
+34
-2
features.py
django/db/backends/postgresql/features.py
+4
-0
introspection.py
django/db/backends/postgresql/introspection.py
+10
-6
indexes.py
django/db/models/indexes.py
+7
-2
indexes.txt
docs/ref/contrib/postgres/indexes.txt
+10
-0
1.11.txt
docs/releases/1.11.txt
+3
-2
test_indexes.py
tests/postgres_tests/test_indexes.py
+52
-2
No files found.
AUTHORS
Dosyayı görüntüle @
e585c43b
...
...
@@ -470,6 +470,7 @@ answer newbie questions, and generally made Django that much better:
Luke Plant <L.Plant.98@cantab.net>
Maciej Fijalkowski
Maciej Wiśniowski <pigletto@gmail.com>
Mads Jensen <https://github.com/atombrella>
Makoto Tsuyuki <mtsuyuki@gmail.com>
Malcolm Tredinnick
Manuel Saelices <msaelices@yaco.es>
...
...
django/contrib/postgres/indexes.py
Dosyayı görüntüle @
e585c43b
from
__future__
import
unicode_literals
from
django.db.models
import
Index
from
django.db.models
.indexes
import
Index
__all__
=
[
'GinIndex'
]
__all__
=
[
'BrinIndex'
,
'GinIndex'
]
class
BrinIndex
(
Index
):
suffix
=
'brin'
def
__init__
(
self
,
fields
=
[],
name
=
None
,
pages_per_range
=
None
):
if
pages_per_range
is
not
None
and
not
(
isinstance
(
pages_per_range
,
int
)
and
pages_per_range
>
0
):
raise
ValueError
(
'pages_per_range must be None or a positive integer for BRIN indexes'
)
self
.
pages_per_range
=
pages_per_range
return
super
(
BrinIndex
,
self
)
.
__init__
(
fields
,
name
)
def
__repr__
(
self
):
if
self
.
pages_per_range
is
not
None
:
return
'<
%(name)
s: fields=
%(fields)
s, pages_per_range=
%(pages_per_range)
s>'
%
{
'name'
:
self
.
__class__
.
__name__
,
'fields'
:
"'{}'"
.
format
(
', '
.
join
(
self
.
fields
)),
'pages_per_range'
:
self
.
pages_per_range
,
}
else
:
return
super
(
BrinIndex
,
self
)
.
__repr__
()
def
deconstruct
(
self
):
path
,
args
,
kwargs
=
super
(
BrinIndex
,
self
)
.
deconstruct
()
kwargs
[
'pages_per_range'
]
=
self
.
pages_per_range
return
path
,
args
,
kwargs
def
get_sql_create_template_values
(
self
,
model
,
schema_editor
,
using
):
parameters
=
super
(
BrinIndex
,
self
)
.
get_sql_create_template_values
(
model
,
schema_editor
,
using
=
' USING brin'
)
if
self
.
pages_per_range
is
not
None
:
parameters
[
'extra'
]
=
' WITH (pages_per_range={})'
.
format
(
schema_editor
.
quote_value
(
self
.
pages_per_range
))
+
parameters
[
'extra'
]
return
parameters
class
GinIndex
(
Index
):
...
...
django/db/backends/postgresql/features.py
Dosyayı görüntüle @
e585c43b
...
...
@@ -37,6 +37,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
def
has_select_for_update_skip_locked
(
self
):
return
self
.
connection
.
pg_version
>=
90500
@cached_property
def
has_brin_index_support
(
self
):
return
self
.
connection
.
pg_version
>=
90500
@cached_property
def
has_jsonb_datatype
(
self
):
return
self
.
connection
.
pg_version
>=
90400
...
...
django/db/backends/postgresql/introspection.py
Dosyayı görüntüle @
e585c43b
...
...
@@ -176,13 +176,14 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
(SELECT fkc.relname || '.' || fka.attname
FROM pg_attribute AS fka
JOIN pg_class AS fkc ON fka.attrelid = fkc.oid
WHERE fka.attrelid = c.confrelid AND fka.attnum = c.confkey[1])
WHERE fka.attrelid = c.confrelid AND fka.attnum = c.confkey[1]),
cl.reloptions
FROM pg_constraint AS c
JOIN pg_class AS cl ON c.conrelid = cl.oid
JOIN pg_namespace AS ns ON cl.relnamespace = ns.oid
WHERE ns.nspname =
%
s AND cl.relname =
%
s
"""
,
[
"public"
,
table_name
])
for
constraint
,
columns
,
kind
,
used_cols
in
cursor
.
fetchall
():
for
constraint
,
columns
,
kind
,
used_cols
,
options
in
cursor
.
fetchall
():
constraints
[
constraint
]
=
{
"columns"
:
columns
,
"primary_key"
:
kind
==
"p"
,
...
...
@@ -191,12 +192,13 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
"check"
:
kind
==
"c"
,
"index"
:
False
,
"definition"
:
None
,
"options"
:
options
,
}
# Now get indexes
cursor
.
execute
(
"""
SELECT
indexname, array_agg(attname), indisunique, indisprimary,
array_agg(ordering), amname, exprdef
array_agg(ordering), amname, exprdef
, s2.attoptions
FROM (
SELECT
c2.relname as indexname, idx.*, attr.attname, am.amname,
...
...
@@ -209,7 +211,8 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
CASE (option & 1)
WHEN 1 THEN 'DESC' ELSE 'ASC'
END
END as ordering
END as ordering,
c2.reloptions as attoptions
FROM (
SELECT
*, unnest(i.indkey) as key, unnest(i.indoption) as option
...
...
@@ -221,9 +224,9 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
LEFT JOIN pg_attribute attr ON attr.attrelid = c.oid AND attr.attnum = idx.key
WHERE c.relname =
%
s
) s2
GROUP BY indexname, indisunique, indisprimary, amname, exprdef;
GROUP BY indexname, indisunique, indisprimary, amname, exprdef
, attoptions
;
"""
,
[
table_name
])
for
index
,
columns
,
unique
,
primary
,
orders
,
type_
,
definition
in
cursor
.
fetchall
():
for
index
,
columns
,
unique
,
primary
,
orders
,
type_
,
definition
,
options
in
cursor
.
fetchall
():
if
index
not
in
constraints
:
constraints
[
index
]
=
{
"columns"
:
columns
if
columns
!=
[
None
]
else
[],
...
...
@@ -235,5 +238,6 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
"index"
:
True
,
"type"
:
type_
,
"definition"
:
definition
,
"options"
:
options
,
}
return
constraints
django/db/models/indexes.py
Dosyayı görüntüle @
e585c43b
...
...
@@ -44,7 +44,7 @@ class Index(object):
self
.
name
=
'D
%
s'
%
self
.
name
[
1
:]
return
errors
def
create_sql
(
self
,
model
,
schema_editor
,
using
=
''
):
def
get_sql_create_template_values
(
self
,
model
,
schema_editor
,
using
):
fields
=
[
model
.
_meta
.
get_field
(
field_name
)
for
field_name
,
order
in
self
.
fields_orders
]
tablespace_sql
=
schema_editor
.
_get_index_tablespace_sql
(
model
,
fields
)
quote_name
=
schema_editor
.
quote_name
...
...
@@ -52,7 +52,7 @@ class Index(object):
(
'
%
s
%
s'
%
(
quote_name
(
field
.
column
),
order
))
.
strip
()
for
field
,
(
field_name
,
order
)
in
zip
(
fields
,
self
.
fields_orders
)
]
return
schema_editor
.
sql_create_index
%
{
return
{
'table'
:
quote_name
(
model
.
_meta
.
db_table
),
'name'
:
quote_name
(
self
.
name
),
'columns'
:
', '
.
join
(
columns
),
...
...
@@ -60,6 +60,11 @@ class Index(object):
'extra'
:
tablespace_sql
,
}
def
create_sql
(
self
,
model
,
schema_editor
,
using
=
''
,
parameters
=
None
):
sql_create_index
=
schema_editor
.
sql_create_index
sql_parameters
=
parameters
or
self
.
get_sql_create_template_values
(
model
,
schema_editor
,
using
)
return
sql_create_index
%
sql_parameters
def
remove_sql
(
self
,
model
,
schema_editor
):
quote_name
=
schema_editor
.
quote_name
return
schema_editor
.
sql_delete_index
%
{
...
...
docs/ref/contrib/postgres/indexes.txt
Dosyayı görüntüle @
e585c43b
...
...
@@ -9,6 +9,16 @@ PostgreSQL specific model indexes
The following are PostgreSQL specific :doc:`indexes </ref/models/indexes>`
available from the ``django.contrib.postgres.indexes`` module.
``BrinIndex``
=============
.. class:: BrinIndex(pages_per_range=None)
Creates a `BRIN index
<https://www.postgresql.org/docs/current/static/brin-intro.html>`_. For
performance considerations and use cases of the index, please consult the
documentation.
``GinIndex``
============
...
...
docs/releases/1.11.txt
Dosyayı görüntüle @
e585c43b
...
...
@@ -212,8 +212,9 @@ Minor features
:class:`~django.contrib.postgres.aggregates.StringAgg` determines if
concatenated values will be distinct.
* The new :class:`~django.contrib.postgres.indexes.GinIndex` class allows
creating gin indexes in the database.
* The new :class:`~django.contrib.postgres.indexes.GinIndex` and
:class:`~django.contrib.postgres.indexes.BrinIndex` classes allow
creating ``GIN`` and ``BRIN`` indexes in the database.
* :class:`~django.contrib.postgres.fields.JSONField` accepts a new ``encoder``
parameter to specify a custom class to encode data types not supported by the
...
...
tests/postgres_tests/test_indexes.py
Dosyayı görüntüle @
e585c43b
from
django.contrib.postgres.indexes
import
GinIndex
from
django.contrib.postgres.indexes
import
BrinIndex
,
GinIndex
from
django.db
import
connection
from
django.test
import
skipUnlessDBFeature
from
.
import
PostgreSQLTestCase
from
.models
import
IntegerArrayModel
from
.models
import
CharFieldModel
,
IntegerArrayModel
@skipUnlessDBFeature
(
'has_brin_index_support'
)
class
BrinIndexTests
(
PostgreSQLTestCase
):
def
test_repr
(
self
):
index
=
BrinIndex
(
fields
=
[
'title'
],
pages_per_range
=
4
)
another_index
=
BrinIndex
(
fields
=
[
'title'
])
self
.
assertEqual
(
repr
(
index
),
"<BrinIndex: fields='title', pages_per_range=4>"
)
self
.
assertEqual
(
repr
(
another_index
),
"<BrinIndex: fields='title'>"
)
def
test_not_eq
(
self
):
index
=
BrinIndex
(
fields
=
[
'title'
])
index_with_page_range
=
BrinIndex
(
fields
=
[
'title'
],
pages_per_range
=
16
)
self
.
assertNotEqual
(
index
,
index_with_page_range
)
def
test_deconstruction
(
self
):
index
=
BrinIndex
(
fields
=
[
'title'
],
name
=
'test_title_brin'
)
path
,
args
,
kwargs
=
index
.
deconstruct
()
self
.
assertEqual
(
path
,
'django.contrib.postgres.indexes.BrinIndex'
)
self
.
assertEqual
(
args
,
())
self
.
assertEqual
(
kwargs
,
{
'fields'
:
[
'title'
],
'name'
:
'test_title_brin'
,
'pages_per_range'
:
None
})
def
test_deconstruction_with_pages_per_rank
(
self
):
index
=
BrinIndex
(
fields
=
[
'title'
],
name
=
'test_title_brin'
,
pages_per_range
=
16
)
path
,
args
,
kwargs
=
index
.
deconstruct
()
self
.
assertEqual
(
path
,
'django.contrib.postgres.indexes.BrinIndex'
)
self
.
assertEqual
(
args
,
())
self
.
assertEqual
(
kwargs
,
{
'fields'
:
[
'title'
],
'name'
:
'test_title_brin'
,
'pages_per_range'
:
16
})
def
test_invalid_pages_per_range
(
self
):
with
self
.
assertRaises
(
ValueError
):
BrinIndex
(
fields
=
[
'title'
],
name
=
'test_title_brin'
,
pages_per_range
=
'Charles Babbage'
)
with
self
.
assertRaises
(
ValueError
):
BrinIndex
(
fields
=
[
'title'
],
name
=
'test_title_brin'
,
pages_per_range
=
0
)
class
GinIndexTests
(
PostgreSQLTestCase
):
...
...
@@ -55,3 +92,16 @@ class SchemaTests(PostgreSQLTestCase):
with
connection
.
schema_editor
()
as
editor
:
editor
.
remove_index
(
IntegerArrayModel
,
index
)
self
.
assertNotIn
(
index_name
,
self
.
get_constraints
(
IntegerArrayModel
.
_meta
.
db_table
))
@skipUnlessDBFeature
(
'has_brin_index_support'
)
def
test_brin_index
(
self
):
index_name
=
'char_field_model_field_brin'
index
=
BrinIndex
(
fields
=
[
'field'
],
name
=
index_name
,
pages_per_range
=
4
)
with
connection
.
schema_editor
()
as
editor
:
editor
.
add_index
(
CharFieldModel
,
index
)
constraints
=
self
.
get_constraints
(
CharFieldModel
.
_meta
.
db_table
)
self
.
assertEqual
(
constraints
[
index_name
][
'type'
],
'brin'
)
self
.
assertEqual
(
constraints
[
index_name
][
'options'
],
[
'pages_per_range=4'
])
with
connection
.
schema_editor
()
as
editor
:
editor
.
remove_index
(
CharFieldModel
,
index
)
self
.
assertNotIn
(
index_name
,
self
.
get_constraints
(
CharFieldModel
.
_meta
.
db_table
))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment