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
738faf9d
Kaydet (Commit)
738faf9d
authored
Ock 19, 2019
tarafından
Dan Tao
Kaydeden (comit)
Tim Graham
Ock 29, 2019
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #30108 -- Allowed adding foreign key constraints in the same statement that adds a field.
üst
9a0cc545
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
69 additions
and
20 deletions
+69
-20
features.py
django/db/backends/base/features.py
+3
-0
schema.py
django/db/backends/base/schema.py
+31
-14
schema.py
django/db/backends/mysql/schema.py
+4
-1
schema.py
django/db/backends/oracle/schema.py
+1
-0
schema.py
django/db/backends/postgresql/schema.py
+1
-0
features.py
django/db/backends/sqlite3/features.py
+1
-0
3.0.txt
docs/releases/3.0.txt
+4
-0
tests.py
tests/indexes/tests.py
+3
-5
tests.py
tests/schema/tests.py
+21
-0
No files found.
django/db/backends/base/features.py
Dosyayı görüntüle @
738faf9d
...
...
@@ -179,6 +179,9 @@ class BaseDatabaseFeatures:
# Does it support foreign keys?
supports_foreign_keys
=
True
# Can it create foreign key constraints inline when adding columns?
can_create_inline_fk
=
True
# Does it support CHECK constraints?
supports_column_check_constraints
=
True
supports_table_check_constraints
=
True
...
...
django/db/backends/base/schema.py
Dosyayı görüntüle @
738faf9d
...
...
@@ -77,6 +77,7 @@ class BaseDatabaseSchemaEditor:
"REFERENCES
%(to_table)
s (
%(to_column)
s)
%(deferrable)
s"
)
sql_create_inline_fk
=
None
sql_create_column_inline_fk
=
None
sql_delete_fk
=
sql_delete_constraint
sql_create_index
=
"CREATE INDEX
%(name)
s ON
%(table)
s (
%(columns)
s)
%(extra)
s
%(condition)
s"
...
...
@@ -433,6 +434,22 @@ class BaseDatabaseSchemaEditor:
db_params
=
field
.
db_parameters
(
connection
=
self
.
connection
)
if
db_params
[
'check'
]:
definition
+=
" "
+
self
.
sql_check_constraint
%
db_params
if
field
.
remote_field
and
self
.
connection
.
features
.
supports_foreign_keys
and
field
.
db_constraint
:
constraint_suffix
=
'_fk_
%(to_table)
s_
%(to_column)
s'
# Add FK constraint inline, if supported.
if
self
.
sql_create_column_inline_fk
:
to_table
=
field
.
remote_field
.
model
.
_meta
.
db_table
to_column
=
field
.
remote_field
.
model
.
_meta
.
get_field
(
field
.
remote_field
.
field_name
)
.
column
definition
+=
" "
+
self
.
sql_create_column_inline_fk
%
{
'name'
:
self
.
_fk_constraint_name
(
model
,
field
,
constraint_suffix
),
'column'
:
self
.
quote_name
(
field
.
column
),
'to_table'
:
self
.
quote_name
(
to_table
),
'to_column'
:
self
.
quote_name
(
to_column
),
'deferrable'
:
self
.
connection
.
ops
.
deferrable_sql
()
}
# Otherwise, add FK constraints later.
else
:
self
.
deferred_sql
.
append
(
self
.
_create_fk_sql
(
model
,
field
,
constraint_suffix
))
# Build the SQL and run it
sql
=
self
.
sql_create_column
%
{
"table"
:
self
.
quote_name
(
model
.
_meta
.
db_table
),
...
...
@@ -451,9 +468,6 @@ class BaseDatabaseSchemaEditor:
self
.
execute
(
sql
,
params
)
# Add an index, if required
self
.
deferred_sql
.
extend
(
self
.
_field_indexes_sql
(
model
,
field
))
# Add any FK constraints later
if
field
.
remote_field
and
self
.
connection
.
features
.
supports_foreign_keys
and
field
.
db_constraint
:
self
.
deferred_sql
.
append
(
self
.
_create_fk_sql
(
model
,
field
,
"_fk_
%(to_table)
s_
%(to_column)
s"
))
# Reset connection if required
if
self
.
connection
.
features
.
connection_persists_old_columns
:
self
.
connection
.
close
()
...
...
@@ -984,18 +998,8 @@ class BaseDatabaseSchemaEditor:
}
def
_create_fk_sql
(
self
,
model
,
field
,
suffix
):
def
create_fk_name
(
*
args
,
**
kwargs
):
return
self
.
quote_name
(
self
.
_create_index_name
(
*
args
,
**
kwargs
))
table
=
Table
(
model
.
_meta
.
db_table
,
self
.
quote_name
)
name
=
ForeignKeyName
(
model
.
_meta
.
db_table
,
[
field
.
column
],
split_identifier
(
field
.
target_field
.
model
.
_meta
.
db_table
)[
1
],
[
field
.
target_field
.
column
],
suffix
,
create_fk_name
,
)
name
=
self
.
_fk_constraint_name
(
model
,
field
,
suffix
)
column
=
Columns
(
model
.
_meta
.
db_table
,
[
field
.
column
],
self
.
quote_name
)
to_table
=
Table
(
field
.
target_field
.
model
.
_meta
.
db_table
,
self
.
quote_name
)
to_column
=
Columns
(
field
.
target_field
.
model
.
_meta
.
db_table
,
[
field
.
target_field
.
column
],
self
.
quote_name
)
...
...
@@ -1010,6 +1014,19 @@ class BaseDatabaseSchemaEditor:
deferrable
=
deferrable
,
)
def
_fk_constraint_name
(
self
,
model
,
field
,
suffix
):
def
create_fk_name
(
*
args
,
**
kwargs
):
return
self
.
quote_name
(
self
.
_create_index_name
(
*
args
,
**
kwargs
))
return
ForeignKeyName
(
model
.
_meta
.
db_table
,
[
field
.
column
],
split_identifier
(
field
.
target_field
.
model
.
_meta
.
db_table
)[
1
],
[
field
.
target_field
.
column
],
suffix
,
create_fk_name
,
)
def
_delete_fk_sql
(
self
,
model
,
name
):
return
self
.
_delete_constraint_sql
(
self
.
sql_delete_fk
,
model
,
name
)
...
...
django/db/backends/mysql/schema.py
Dosyayı görüntüle @
738faf9d
...
...
@@ -16,7 +16,10 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
sql_rename_column
=
"ALTER TABLE
%(table)
s CHANGE
%(old_column)
s
%(new_column)
s
%(type)
s"
sql_delete_unique
=
"ALTER TABLE
%(table)
s DROP INDEX
%(name)
s"
sql_create_column_inline_fk
=
(
', ADD CONSTRAINT
%(name)
s FOREIGN KEY (
%(column)
s) '
'REFERENCES
%(to_table)
s(
%(to_column)
s)'
)
sql_delete_fk
=
"ALTER TABLE
%(table)
s DROP FOREIGN KEY
%(name)
s"
sql_delete_index
=
"DROP INDEX
%(name)
s ON
%(table)
s"
...
...
django/db/backends/oracle/schema.py
Dosyayı görüntüle @
738faf9d
...
...
@@ -15,6 +15,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
sql_alter_column_default
=
"MODIFY
%(column)
s DEFAULT
%(default)
s"
sql_alter_column_no_default
=
"MODIFY
%(column)
s DEFAULT NULL"
sql_delete_column
=
"ALTER TABLE
%(table)
s DROP COLUMN
%(column)
s"
sql_create_column_inline_fk
=
'CONSTRAINT
%(name)
s REFERENCES
%(to_table)
s(
%(to_column)
s)
%(deferrable)
s'
sql_delete_table
=
"DROP TABLE
%(table)
s CASCADE CONSTRAINTS"
sql_create_index
=
"CREATE INDEX
%(name)
s ON
%(table)
s (
%(columns)
s)
%(extra)
s"
...
...
django/db/backends/postgresql/schema.py
Dosyayı görüntüle @
738faf9d
...
...
@@ -15,6 +15,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
sql_create_index
=
"CREATE INDEX
%(name)
s ON
%(table)
s
%(using)
s (
%(columns)
s)
%(extra)
s
%(condition)
s"
sql_delete_index
=
"DROP INDEX IF EXISTS
%(name)
s"
sql_create_column_inline_fk
=
'REFERENCES
%(to_table)
s(
%(to_column)
s)
%(deferrable)
s'
# Setting the constraint to IMMEDIATE runs any deferred checks to allow
# dropping it in the same transaction.
sql_delete_fk
=
"SET CONSTRAINTS
%(name)
s IMMEDIATE; ALTER TABLE
%(table)
s DROP CONSTRAINT
%(name)
s"
...
...
django/db/backends/sqlite3/features.py
Dosyayı görüntüle @
738faf9d
...
...
@@ -26,6 +26,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
atomic_transactions
=
False
can_rollback_ddl
=
True
supports_atomic_references_rename
=
Database
.
sqlite_version_info
>=
(
3
,
26
,
0
)
can_create_inline_fk
=
False
supports_paramstyle_pyformat
=
False
supports_sequence_reset
=
False
can_clone_databases
=
True
...
...
docs/releases/3.0.txt
Dosyayı görüntüle @
738faf9d
...
...
@@ -214,6 +214,10 @@ backends.
* ``DatabaseIntrospection.get_field_type()`` may no longer return tuples.
* If the database can create foreign keys in the same SQL statement that adds a
field, add ``SchemaEditor.sql_create_column_inline_fk`` with the appropriate
SQL; otherwise, set ``DatabaseFeatures.can_create_inline_fk = False``.
Miscellaneous
-------------
...
...
tests/indexes/tests.py
Dosyayı görüntüle @
738faf9d
...
...
@@ -226,11 +226,9 @@ class SchemaIndexesMySQLTests(TransactionTestCase):
new_field
.
set_attributes_from_name
(
'new_foreign_key'
)
editor
.
add_field
(
ArticleTranslation
,
new_field
)
field_created
=
True
self
.
assertEqual
([
str
(
statement
)
for
statement
in
editor
.
deferred_sql
],
[
'ALTER TABLE `indexes_articletranslation` '
'ADD CONSTRAINT `indexes_articletrans_new_foreign_key_id_d27a9146_fk_indexes_a` '
'FOREIGN KEY (`new_foreign_key_id`) REFERENCES `indexes_article` (`id`)'
])
# No deferred SQL. The FK constraint is included in the
# statement to add the field.
self
.
assertFalse
(
editor
.
deferred_sql
)
finally
:
if
field_created
:
with
connection
.
schema_editor
()
as
editor
:
...
...
tests/schema/tests.py
Dosyayı görüntüle @
738faf9d
...
...
@@ -241,6 +241,27 @@ class SchemaTests(TransactionTestCase):
editor
.
alter_field
(
Book
,
old_field
,
new_field
,
strict
=
True
)
self
.
assertForeignKeyExists
(
Book
,
'author_id'
,
'schema_tag'
)
@skipUnlessDBFeature
(
'can_create_inline_fk'
)
def
test_inline_fk
(
self
):
# Create some tables.
with
connection
.
schema_editor
()
as
editor
:
editor
.
create_model
(
Author
)
editor
.
create_model
(
Book
)
editor
.
create_model
(
Note
)
self
.
assertForeignKeyNotExists
(
Note
,
'book_id'
,
'schema_book'
)
# Add a foreign key from one to the other.
with
connection
.
schema_editor
()
as
editor
:
new_field
=
ForeignKey
(
Book
,
CASCADE
)
new_field
.
set_attributes_from_name
(
'book'
)
editor
.
add_field
(
Note
,
new_field
)
self
.
assertForeignKeyExists
(
Note
,
'book_id'
,
'schema_book'
)
# Creating a FK field with a constraint uses a single statement without
# a deferred ALTER TABLE.
self
.
assertFalse
([
sql
for
sql
in
(
str
(
statement
)
for
statement
in
editor
.
deferred_sql
)
if
sql
.
startswith
(
'ALTER TABLE'
)
and
'ADD CONSTRAINT'
in
sql
])
@skipUnlessDBFeature
(
'supports_foreign_keys'
)
def
test_char_field_with_db_index_to_fk
(
self
):
# Create the 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