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
095c1aaa
Kaydet (Commit)
095c1aaa
authored
Kas 27, 2017
tarafından
Simon Charette
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #28849 -- Fixed referenced table and column rename on SQLite.
Thanks Ramiro for the input and Tim for the review.
üst
474bd7a5
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
179 additions
and
22 deletions
+179
-22
schema.py
django/contrib/gis/db/backends/spatialite/schema.py
+2
-2
features.py
django/db/backends/base/features.py
+3
-0
features.py
django/db/backends/sqlite3/features.py
+1
-0
schema.py
django/db/backends/sqlite3/schema.py
+58
-2
2.0.txt
docs/releases/2.0.txt
+7
-0
models.py
tests/backends/models.py
+8
-0
tests.py
tests/backends/sqlite/tests.py
+41
-1
test_operations.py
tests/migrations/test_operations.py
+14
-12
tests.py
tests/schema/tests.py
+45
-5
No files found.
django/contrib/gis/db/backends/spatialite/schema.py
Dosyayı görüntüle @
095c1aaa
...
@@ -123,7 +123,7 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor):
...
@@ -123,7 +123,7 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor):
else
:
else
:
super
()
.
remove_field
(
model
,
field
)
super
()
.
remove_field
(
model
,
field
)
def
alter_db_table
(
self
,
model
,
old_db_table
,
new_db_table
):
def
alter_db_table
(
self
,
model
,
old_db_table
,
new_db_table
,
disable_constraints
=
True
):
from
django.contrib.gis.db.models.fields
import
GeometryField
from
django.contrib.gis.db.models.fields
import
GeometryField
# Remove geometry-ness from temp table
# Remove geometry-ness from temp table
for
field
in
model
.
_meta
.
local_fields
:
for
field
in
model
.
_meta
.
local_fields
:
...
@@ -135,7 +135,7 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor):
...
@@ -135,7 +135,7 @@ class SpatialiteSchemaEditor(DatabaseSchemaEditor):
}
}
)
)
# Alter table
# Alter table
super
()
.
alter_db_table
(
model
,
old_db_table
,
new_db_table
)
super
()
.
alter_db_table
(
model
,
old_db_table
,
new_db_table
,
disable_constraints
)
# Repoint any straggler names
# Repoint any straggler names
for
geom_table
in
self
.
geometry_tables
:
for
geom_table
in
self
.
geometry_tables
:
try
:
try
:
...
...
django/db/backends/base/features.py
Dosyayı görüntüle @
095c1aaa
...
@@ -164,6 +164,9 @@ class BaseDatabaseFeatures:
...
@@ -164,6 +164,9 @@ class BaseDatabaseFeatures:
# Can we roll back DDL in a transaction?
# Can we roll back DDL in a transaction?
can_rollback_ddl
=
False
can_rollback_ddl
=
False
# Does it support operations requiring references rename in a transaction?
supports_atomic_references_rename
=
True
# Can we issue more than one ALTER COLUMN clause in an ALTER TABLE?
# Can we issue more than one ALTER COLUMN clause in an ALTER TABLE?
supports_combined_alters
=
False
supports_combined_alters
=
False
...
...
django/db/backends/sqlite3/features.py
Dosyayı görüntüle @
095c1aaa
...
@@ -22,6 +22,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
...
@@ -22,6 +22,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_transactions
=
True
supports_transactions
=
True
atomic_transactions
=
False
atomic_transactions
=
False
can_rollback_ddl
=
True
can_rollback_ddl
=
True
supports_atomic_references_rename
=
False
supports_paramstyle_pyformat
=
False
supports_paramstyle_pyformat
=
False
supports_sequence_reset
=
False
supports_sequence_reset
=
False
can_clone_databases
=
True
can_clone_databases
=
True
...
...
django/db/backends/sqlite3/schema.py
Dosyayı görüntüle @
095c1aaa
...
@@ -5,6 +5,8 @@ from decimal import Decimal
...
@@ -5,6 +5,8 @@ from decimal import Decimal
from
django.apps.registry
import
Apps
from
django.apps.registry
import
Apps
from
django.db.backends.base.schema
import
BaseDatabaseSchemaEditor
from
django.db.backends.base.schema
import
BaseDatabaseSchemaEditor
from
django.db.backends.ddl_references
import
Statement
from
django.db.backends.ddl_references
import
Statement
from
django.db.transaction
import
atomic
from
django.db.utils
import
NotSupportedError
class
DatabaseSchemaEditor
(
BaseDatabaseSchemaEditor
):
class
DatabaseSchemaEditor
(
BaseDatabaseSchemaEditor
):
...
@@ -53,6 +55,58 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
...
@@ -53,6 +55,58 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
else
:
else
:
raise
ValueError
(
"Cannot quote parameter value
%
r of type
%
s"
%
(
value
,
type
(
value
)))
raise
ValueError
(
"Cannot quote parameter value
%
r of type
%
s"
%
(
value
,
type
(
value
)))
def
alter_db_table
(
self
,
model
,
old_db_table
,
new_db_table
,
disable_constraints
=
True
):
if
model
.
_meta
.
related_objects
and
disable_constraints
:
if
self
.
connection
.
in_atomic_block
:
raise
NotSupportedError
((
'Renaming the
%
r table while in a transaction is not '
'supported on SQLite because it would break referential '
'integrity. Try adding `atomic = False` to the Migration class.'
)
%
old_db_table
)
self
.
connection
.
enable_constraint_checking
()
super
()
.
alter_db_table
(
model
,
old_db_table
,
new_db_table
)
self
.
connection
.
disable_constraint_checking
()
else
:
super
()
.
alter_db_table
(
model
,
old_db_table
,
new_db_table
)
def
alter_field
(
self
,
model
,
old_field
,
new_field
,
strict
=
False
):
old_field_name
=
old_field
.
name
if
(
new_field
.
name
!=
old_field_name
and
any
(
r
.
field_name
==
old_field
.
name
for
r
in
model
.
_meta
.
related_objects
)):
if
self
.
connection
.
in_atomic_block
:
raise
NotSupportedError
((
'Renaming the
%
r.
%
r column while in a transaction is not '
'supported on SQLite because it would break referential '
'integrity. Try adding `atomic = False` to the Migration class.'
)
%
(
model
.
_meta
.
db_table
,
old_field_name
))
with
atomic
(
self
.
connection
.
alias
):
super
()
.
alter_field
(
model
,
old_field
,
new_field
,
strict
=
strict
)
# Follow SQLite's documented procedure for performing changes
# that don't affect the on-disk content.
# https://sqlite.org/lang_altertable.html#otheralter
with
self
.
connection
.
cursor
()
as
cursor
:
schema_version
=
cursor
.
execute
(
'PRAGMA schema_version'
)
.
fetchone
()[
0
]
cursor
.
execute
(
'PRAGMA writable_schema = 1'
)
table_name
=
model
.
_meta
.
db_table
references_template
=
' REFERENCES "
%
s" ("
%%
s") '
%
table_name
old_column_name
=
old_field
.
get_attname_column
()[
1
]
new_column_name
=
new_field
.
get_attname_column
()[
1
]
search
=
references_template
%
old_column_name
replacement
=
references_template
%
new_column_name
cursor
.
execute
(
'UPDATE sqlite_master SET sql = replace(sql,
%
s,
%
s)'
,
(
search
,
replacement
))
cursor
.
execute
(
'PRAGMA schema_version =
%
d'
%
(
schema_version
+
1
))
cursor
.
execute
(
'PRAGMA writable_schema = 0'
)
# The integrity check will raise an exception and rollback
# the transaction if the sqlite_master updates corrupt the
# database.
cursor
.
execute
(
'PRAGMA integrity_check'
)
# Perform a VACUUM to refresh the database representation from
# the sqlite_master table.
with
self
.
connection
.
cursor
()
as
cursor
:
cursor
.
execute
(
'VACUUM'
)
else
:
super
()
.
alter_field
(
model
,
old_field
,
new_field
,
strict
=
strict
)
def
_remake_table
(
self
,
model
,
create_field
=
None
,
delete_field
=
None
,
alter_field
=
None
):
def
_remake_table
(
self
,
model
,
create_field
=
None
,
delete_field
=
None
,
alter_field
=
None
):
"""
"""
Shortcut to transform a model from old_model into new_model
Shortcut to transform a model from old_model into new_model
...
@@ -176,8 +230,10 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
...
@@ -176,8 +230,10 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
with
altered_table_name
(
model
,
model
.
_meta
.
db_table
+
"__old"
):
with
altered_table_name
(
model
,
model
.
_meta
.
db_table
+
"__old"
):
# Rename the old table to make way for the new
# Rename the old table to make way for the new
self
.
alter_db_table
(
model
,
temp_model
.
_meta
.
db_table
,
model
.
_meta
.
db_table
)
self
.
alter_db_table
(
model
,
temp_model
.
_meta
.
db_table
,
model
.
_meta
.
db_table
,
disable_constraints
=
False
,
)
# Create a new table with the updated schema.
# Create a new table with the updated schema.
self
.
create_model
(
temp_model
)
self
.
create_model
(
temp_model
)
...
...
docs/releases/2.0.txt
Dosyayı görüntüle @
095c1aaa
...
@@ -534,6 +534,13 @@ rebuild tables using a script similar to this::
...
@@ -534,6 +534,13 @@ rebuild tables using a script similar to this::
This script hasn't received extensive testing and needs adaption for various
This script hasn't received extensive testing and needs adaption for various
cases such as multiple databases. Feel free to contribute improvements.
cases such as multiple databases. Feel free to contribute improvements.
In addition, because of a table alteration limitation of SQLite, it's prohibited
to perform :class:`~django.db.migrations.operations.RenameModel` and
:class:`~django.db.migrations.operations.RenameField` operations on models or
fields referenced by other models in a transaction. In order to allow migrations
containing these operations to be applied, you must set the
``Migration.atomic`` attribute to ``False``.
Miscellaneous
Miscellaneous
-------------
-------------
...
...
tests/backends/models.py
Dosyayı görüntüle @
095c1aaa
...
@@ -103,3 +103,11 @@ class ObjectReference(models.Model):
...
@@ -103,3 +103,11 @@ class ObjectReference(models.Model):
class
RawData
(
models
.
Model
):
class
RawData
(
models
.
Model
):
raw_data
=
models
.
BinaryField
()
raw_data
=
models
.
BinaryField
()
class
Author
(
models
.
Model
):
name
=
models
.
CharField
(
max_length
=
255
,
unique
=
True
)
class
Book
(
models
.
Model
):
author
=
models
.
ForeignKey
(
Author
,
models
.
CASCADE
,
to_field
=
'name'
)
tests/backends/sqlite/tests.py
Dosyayı görüntüle @
095c1aaa
...
@@ -4,10 +4,12 @@ import unittest
...
@@ -4,10 +4,12 @@ import unittest
from
django.db
import
connection
from
django.db
import
connection
from
django.db.models
import
Avg
,
StdDev
,
Sum
,
Variance
from
django.db.models
import
Avg
,
StdDev
,
Sum
,
Variance
from
django.db.models.fields
import
CharField
from
django.db.utils
import
NotSupportedError
from
django.db.utils
import
NotSupportedError
from
django.test
import
TestCase
,
TransactionTestCase
,
override_settings
from
django.test
import
TestCase
,
TransactionTestCase
,
override_settings
from
django.test.utils
import
isolate_apps
from
..models
import
Item
,
Object
,
Square
from
..models
import
Author
,
Item
,
Object
,
Square
@unittest.skipUnless
(
connection
.
vendor
==
'sqlite'
,
'SQLite tests'
)
@unittest.skipUnless
(
connection
.
vendor
==
'sqlite'
,
'SQLite tests'
)
...
@@ -58,6 +60,44 @@ class Tests(TestCase):
...
@@ -58,6 +60,44 @@ class Tests(TestCase):
self
.
assertEqual
(
creation
.
_get_test_db_name
(),
creation
.
connection
.
settings_dict
[
'TEST'
][
'NAME'
])
self
.
assertEqual
(
creation
.
_get_test_db_name
(),
creation
.
connection
.
settings_dict
[
'TEST'
][
'NAME'
])
@unittest.skipUnless
(
connection
.
vendor
==
'sqlite'
,
'SQLite tests'
)
@isolate_apps
(
'backends'
)
class
SchemaTests
(
TransactionTestCase
):
available_apps
=
[
'backends'
]
def
test_field_rename_inside_atomic_block
(
self
):
"""
NotImplementedError is raised when a model field rename is attempted
inside an atomic block.
"""
new_field
=
CharField
(
max_length
=
255
,
unique
=
True
)
new_field
.
set_attributes_from_name
(
'renamed'
)
msg
=
(
"Renaming the 'backends_author'.'name' column while in a "
"transaction is not supported on SQLite because it would break "
"referential integrity. Try adding `atomic = False` to the "
"Migration class."
)
with
self
.
assertRaisesMessage
(
NotSupportedError
,
msg
):
with
connection
.
schema_editor
(
atomic
=
True
)
as
editor
:
editor
.
alter_field
(
Author
,
Author
.
_meta
.
get_field
(
'name'
),
new_field
)
def
test_table_rename_inside_atomic_block
(
self
):
"""
NotImplementedError is raised when a table rename is attempted inside
an atomic block.
"""
msg
=
(
"Renaming the 'backends_author' table while in a transaction is "
"not supported on SQLite because it would break referential "
"integrity. Try adding `atomic = False` to the Migration class."
)
with
self
.
assertRaisesMessage
(
NotSupportedError
,
msg
):
with
connection
.
schema_editor
(
atomic
=
True
)
as
editor
:
editor
.
alter_db_table
(
Author
,
"backends_author"
,
"renamed_table"
)
@unittest.skipUnless
(
connection
.
vendor
==
'sqlite'
,
'Test only for SQLite'
)
@unittest.skipUnless
(
connection
.
vendor
==
'sqlite'
,
'Test only for SQLite'
)
@override_settings
(
DEBUG
=
True
)
@override_settings
(
DEBUG
=
True
)
class
LastExecutedQueryTest
(
TestCase
):
class
LastExecutedQueryTest
(
TestCase
):
...
...
tests/migrations/test_operations.py
Dosyayı görüntüle @
095c1aaa
...
@@ -28,16 +28,16 @@ class OperationTestBase(MigrationTestBase):
...
@@ -28,16 +28,16 @@ class OperationTestBase(MigrationTestBase):
Common functions to help test operations.
Common functions to help test operations.
"""
"""
def
apply_operations
(
self
,
app_label
,
project_state
,
operations
):
def
apply_operations
(
self
,
app_label
,
project_state
,
operations
,
atomic
=
True
):
migration
=
Migration
(
'name'
,
app_label
)
migration
=
Migration
(
'name'
,
app_label
)
migration
.
operations
=
operations
migration
.
operations
=
operations
with
connection
.
schema_editor
()
as
editor
:
with
connection
.
schema_editor
(
atomic
=
atomic
)
as
editor
:
return
migration
.
apply
(
project_state
,
editor
)
return
migration
.
apply
(
project_state
,
editor
)
def
unapply_operations
(
self
,
app_label
,
project_state
,
operations
):
def
unapply_operations
(
self
,
app_label
,
project_state
,
operations
,
atomic
=
True
):
migration
=
Migration
(
'name'
,
app_label
)
migration
=
Migration
(
'name'
,
app_label
)
migration
.
operations
=
operations
migration
.
operations
=
operations
with
connection
.
schema_editor
()
as
editor
:
with
connection
.
schema_editor
(
atomic
=
atomic
)
as
editor
:
return
migration
.
unapply
(
project_state
,
editor
)
return
migration
.
unapply
(
project_state
,
editor
)
def
make_test_state
(
self
,
app_label
,
operation
,
**
kwargs
):
def
make_test_state
(
self
,
app_label
,
operation
,
**
kwargs
):
...
@@ -561,7 +561,8 @@ class OperationTests(OperationTestBase):
...
@@ -561,7 +561,8 @@ class OperationTests(OperationTestBase):
self
.
assertFKNotExists
(
"test_rnmo_rider"
,
[
"pony_id"
],
(
"test_rnmo_horse"
,
"id"
))
self
.
assertFKNotExists
(
"test_rnmo_rider"
,
[
"pony_id"
],
(
"test_rnmo_horse"
,
"id"
))
# Migrate forwards
# Migrate forwards
new_state
=
project_state
.
clone
()
new_state
=
project_state
.
clone
()
new_state
=
self
.
apply_operations
(
"test_rnmo"
,
new_state
,
[
operation
])
atomic_rename
=
connection
.
features
.
supports_atomic_references_rename
new_state
=
self
.
apply_operations
(
"test_rnmo"
,
new_state
,
[
operation
],
atomic
=
atomic_rename
)
# Test new state and database
# Test new state and database
self
.
assertNotIn
((
"test_rnmo"
,
"pony"
),
new_state
.
models
)
self
.
assertNotIn
((
"test_rnmo"
,
"pony"
),
new_state
.
models
)
self
.
assertIn
((
"test_rnmo"
,
"horse"
),
new_state
.
models
)
self
.
assertIn
((
"test_rnmo"
,
"horse"
),
new_state
.
models
)
...
@@ -573,7 +574,7 @@ class OperationTests(OperationTestBase):
...
@@ -573,7 +574,7 @@ class OperationTests(OperationTestBase):
self
.
assertFKNotExists
(
"test_rnmo_rider"
,
[
"pony_id"
],
(
"test_rnmo_pony"
,
"id"
))
self
.
assertFKNotExists
(
"test_rnmo_rider"
,
[
"pony_id"
],
(
"test_rnmo_pony"
,
"id"
))
self
.
assertFKExists
(
"test_rnmo_rider"
,
[
"pony_id"
],
(
"test_rnmo_horse"
,
"id"
))
self
.
assertFKExists
(
"test_rnmo_rider"
,
[
"pony_id"
],
(
"test_rnmo_horse"
,
"id"
))
# Migrate backwards
# Migrate backwards
original_state
=
self
.
unapply_operations
(
"test_rnmo"
,
project_state
,
[
operation
])
original_state
=
self
.
unapply_operations
(
"test_rnmo"
,
project_state
,
[
operation
]
,
atomic
=
atomic_rename
)
# Test original state and database
# Test original state and database
self
.
assertIn
((
"test_rnmo"
,
"pony"
),
original_state
.
models
)
self
.
assertIn
((
"test_rnmo"
,
"pony"
),
original_state
.
models
)
self
.
assertNotIn
((
"test_rnmo"
,
"horse"
),
original_state
.
models
)
self
.
assertNotIn
((
"test_rnmo"
,
"horse"
),
original_state
.
models
)
...
@@ -634,7 +635,8 @@ class OperationTests(OperationTestBase):
...
@@ -634,7 +635,8 @@ class OperationTests(OperationTestBase):
if
connection
.
features
.
supports_foreign_keys
:
if
connection
.
features
.
supports_foreign_keys
:
self
.
assertFKExists
(
"test_rmwsrf_rider"
,
[
"friend_id"
],
(
"test_rmwsrf_rider"
,
"id"
))
self
.
assertFKExists
(
"test_rmwsrf_rider"
,
[
"friend_id"
],
(
"test_rmwsrf_rider"
,
"id"
))
self
.
assertFKNotExists
(
"test_rmwsrf_rider"
,
[
"friend_id"
],
(
"test_rmwsrf_horserider"
,
"id"
))
self
.
assertFKNotExists
(
"test_rmwsrf_rider"
,
[
"friend_id"
],
(
"test_rmwsrf_horserider"
,
"id"
))
with
connection
.
schema_editor
()
as
editor
:
atomic_rename
=
connection
.
features
.
supports_atomic_references_rename
with
connection
.
schema_editor
(
atomic
=
atomic_rename
)
as
editor
:
operation
.
database_forwards
(
"test_rmwsrf"
,
editor
,
project_state
,
new_state
)
operation
.
database_forwards
(
"test_rmwsrf"
,
editor
,
project_state
,
new_state
)
self
.
assertTableNotExists
(
"test_rmwsrf_rider"
)
self
.
assertTableNotExists
(
"test_rmwsrf_rider"
)
self
.
assertTableExists
(
"test_rmwsrf_horserider"
)
self
.
assertTableExists
(
"test_rmwsrf_horserider"
)
...
@@ -642,7 +644,7 @@ class OperationTests(OperationTestBase):
...
@@ -642,7 +644,7 @@ class OperationTests(OperationTestBase):
self
.
assertFKNotExists
(
"test_rmwsrf_horserider"
,
[
"friend_id"
],
(
"test_rmwsrf_rider"
,
"id"
))
self
.
assertFKNotExists
(
"test_rmwsrf_horserider"
,
[
"friend_id"
],
(
"test_rmwsrf_rider"
,
"id"
))
self
.
assertFKExists
(
"test_rmwsrf_horserider"
,
[
"friend_id"
],
(
"test_rmwsrf_horserider"
,
"id"
))
self
.
assertFKExists
(
"test_rmwsrf_horserider"
,
[
"friend_id"
],
(
"test_rmwsrf_horserider"
,
"id"
))
# And test reversal
# And test reversal
with
connection
.
schema_editor
()
as
editor
:
with
connection
.
schema_editor
(
atomic
=
atomic_rename
)
as
editor
:
operation
.
database_backwards
(
"test_rmwsrf"
,
editor
,
new_state
,
project_state
)
operation
.
database_backwards
(
"test_rmwsrf"
,
editor
,
new_state
,
project_state
)
self
.
assertTableExists
(
"test_rmwsrf_rider"
)
self
.
assertTableExists
(
"test_rmwsrf_rider"
)
self
.
assertTableNotExists
(
"test_rmwsrf_horserider"
)
self
.
assertTableNotExists
(
"test_rmwsrf_horserider"
)
...
@@ -675,7 +677,7 @@ class OperationTests(OperationTestBase):
...
@@ -675,7 +677,7 @@ class OperationTests(OperationTestBase):
# and the foreign key on rider points to pony, not shetland pony
# and the foreign key on rider points to pony, not shetland pony
self
.
assertFKExists
(
"test_rmwsc_rider"
,
[
"pony_id"
],
(
"test_rmwsc_pony"
,
"id"
))
self
.
assertFKExists
(
"test_rmwsc_rider"
,
[
"pony_id"
],
(
"test_rmwsc_pony"
,
"id"
))
self
.
assertFKNotExists
(
"test_rmwsc_rider"
,
[
"pony_id"
],
(
"test_rmwsc_shetlandpony"
,
"id"
))
self
.
assertFKNotExists
(
"test_rmwsc_rider"
,
[
"pony_id"
],
(
"test_rmwsc_shetlandpony"
,
"id"
))
with
connection
.
schema_editor
()
as
editor
:
with
connection
.
schema_editor
(
atomic
=
connection
.
features
.
supports_atomic_references_rename
)
as
editor
:
operation
.
database_forwards
(
"test_rmwsc"
,
editor
,
project_state
,
new_state
)
operation
.
database_forwards
(
"test_rmwsc"
,
editor
,
project_state
,
new_state
)
# Now we have a little horse table, not shetland pony
# Now we have a little horse table, not shetland pony
self
.
assertTableNotExists
(
"test_rmwsc_shetlandpony"
)
self
.
assertTableNotExists
(
"test_rmwsc_shetlandpony"
)
...
@@ -696,7 +698,7 @@ class OperationTests(OperationTestBase):
...
@@ -696,7 +698,7 @@ class OperationTests(OperationTestBase):
])
])
project_state
=
self
.
apply_operations
(
app_label
,
project_state
,
operations
=
[
project_state
=
self
.
apply_operations
(
app_label
,
project_state
,
operations
=
[
migrations
.
RenameModel
(
"ReflexivePony"
,
"ReflexivePony2"
),
migrations
.
RenameModel
(
"ReflexivePony"
,
"ReflexivePony2"
),
])
]
,
atomic
=
connection
.
features
.
supports_atomic_references_rename
)
Pony
=
project_state
.
apps
.
get_model
(
app_label
,
"ReflexivePony2"
)
Pony
=
project_state
.
apps
.
get_model
(
app_label
,
"ReflexivePony2"
)
pony
=
Pony
.
objects
.
create
()
pony
=
Pony
.
objects
.
create
()
pony
.
ponies
.
add
(
pony
)
pony
.
ponies
.
add
(
pony
)
...
@@ -749,7 +751,7 @@ class OperationTests(OperationTestBase):
...
@@ -749,7 +751,7 @@ class OperationTests(OperationTestBase):
project_state
=
self
.
apply_operations
(
app_label
,
project_state
,
operations
=
[
project_state
=
self
.
apply_operations
(
app_label
,
project_state
,
operations
=
[
migrations
.
RenameModel
(
"Rider"
,
"Rider2"
),
migrations
.
RenameModel
(
"Rider"
,
"Rider2"
),
])
]
,
atomic
=
connection
.
features
.
supports_atomic_references_rename
)
Pony
=
project_state
.
apps
.
get_model
(
app_label
,
"Pony"
)
Pony
=
project_state
.
apps
.
get_model
(
app_label
,
"Pony"
)
Rider
=
project_state
.
apps
.
get_model
(
app_label
,
"Rider2"
)
Rider
=
project_state
.
apps
.
get_model
(
app_label
,
"Rider2"
)
pony
=
Pony
.
objects
.
create
()
pony
=
Pony
.
objects
.
create
()
...
@@ -1397,7 +1399,7 @@ class OperationTests(OperationTestBase):
...
@@ -1397,7 +1399,7 @@ class OperationTests(OperationTestBase):
project_state
=
self
.
apply_operations
(
app_label
,
project_state
,
operations
=
[
project_state
=
self
.
apply_operations
(
app_label
,
project_state
,
operations
=
[
migrations
.
RenameField
(
'Rider'
,
'id'
,
'id2'
),
migrations
.
RenameField
(
'Rider'
,
'id'
,
'id2'
),
migrations
.
AlterField
(
'Pony'
,
'id'
,
models
.
CharField
(
primary_key
=
True
,
max_length
=
99
)),
migrations
.
AlterField
(
'Pony'
,
'id'
,
models
.
CharField
(
primary_key
=
True
,
max_length
=
99
)),
])
]
,
atomic
=
connection
.
features
.
supports_atomic_references_rename
)
def
test_rename_field
(
self
):
def
test_rename_field
(
self
):
"""
"""
...
...
tests/schema/tests.py
Dosyayı görüntüle @
095c1aaa
...
@@ -173,7 +173,7 @@ class SchemaTests(TransactionTestCase):
...
@@ -173,7 +173,7 @@ class SchemaTests(TransactionTestCase):
index_orders
=
constraints
[
index
][
'orders'
]
index_orders
=
constraints
[
index
][
'orders'
]
self
.
assertTrue
(
all
(
val
==
expected
for
val
,
expected
in
zip
(
index_orders
,
order
)))
self
.
assertTrue
(
all
(
val
==
expected
for
val
,
expected
in
zip
(
index_orders
,
order
)))
def
assertForeignKeyExists
(
self
,
model
,
column
,
expected_fk_table
):
def
assertForeignKeyExists
(
self
,
model
,
column
,
expected_fk_table
,
field
=
'id'
):
"""
"""
Fail if the FK constraint on `model.Meta.db_table`.`column` to
Fail if the FK constraint on `model.Meta.db_table`.`column` to
`expected_fk_table`.id doesn't exist.
`expected_fk_table`.id doesn't exist.
...
@@ -184,7 +184,7 @@ class SchemaTests(TransactionTestCase):
...
@@ -184,7 +184,7 @@ class SchemaTests(TransactionTestCase):
if
details
[
'columns'
]
==
[
column
]
and
details
[
'foreign_key'
]:
if
details
[
'columns'
]
==
[
column
]
and
details
[
'foreign_key'
]:
constraint_fk
=
details
[
'foreign_key'
]
constraint_fk
=
details
[
'foreign_key'
]
break
break
self
.
assertEqual
(
constraint_fk
,
(
expected_fk_table
,
'id'
))
self
.
assertEqual
(
constraint_fk
,
(
expected_fk_table
,
field
))
def
assertForeignKeyNotExists
(
self
,
model
,
column
,
expected_fk_table
):
def
assertForeignKeyNotExists
(
self
,
model
,
column
,
expected_fk_table
):
with
self
.
assertRaises
(
AssertionError
):
with
self
.
assertRaises
(
AssertionError
):
...
@@ -1147,6 +1147,30 @@ class SchemaTests(TransactionTestCase):
...
@@ -1147,6 +1147,30 @@ class SchemaTests(TransactionTestCase):
self
.
assertEqual
(
columns
[
'display_name'
][
0
],
"CharField"
)
self
.
assertEqual
(
columns
[
'display_name'
][
0
],
"CharField"
)
self
.
assertNotIn
(
"name"
,
columns
)
self
.
assertNotIn
(
"name"
,
columns
)
@isolate_apps
(
'schema'
)
def
test_rename_referenced_field
(
self
):
class
Author
(
Model
):
name
=
CharField
(
max_length
=
255
,
unique
=
True
)
class
Meta
:
app_label
=
'schema'
class
Book
(
Model
):
author
=
ForeignKey
(
Author
,
CASCADE
,
to_field
=
'name'
)
class
Meta
:
app_label
=
'schema'
with
connection
.
schema_editor
()
as
editor
:
editor
.
create_model
(
Author
)
editor
.
create_model
(
Book
)
new_field
=
CharField
(
max_length
=
255
,
unique
=
True
)
new_field
.
set_attributes_from_name
(
'renamed'
)
with
connection
.
schema_editor
(
atomic
=
connection
.
features
.
supports_atomic_references_rename
)
as
editor
:
editor
.
alter_field
(
Author
,
Author
.
_meta
.
get_field
(
'name'
),
new_field
)
# Ensure the foreign key reference was updated.
self
.
assertForeignKeyExists
(
Book
,
'author_id'
,
'schema_author'
,
'renamed'
)
@skipIfDBFeature
(
'interprets_empty_strings_as_nulls'
)
@skipIfDBFeature
(
'interprets_empty_strings_as_nulls'
)
def
test_rename_keep_null_status
(
self
):
def
test_rename_keep_null_status
(
self
):
"""
"""
...
@@ -1625,25 +1649,41 @@ class SchemaTests(TransactionTestCase):
...
@@ -1625,25 +1649,41 @@ class SchemaTests(TransactionTestCase):
),
),
)
)
@isolate_apps
(
'schema'
)
def
test_db_table
(
self
):
def
test_db_table
(
self
):
"""
"""
Tests renaming of the table
Tests renaming of the table
"""
"""
# Create the table
class
Author
(
Model
):
name
=
CharField
(
max_length
=
255
)
class
Meta
:
app_label
=
'schema'
class
Book
(
Model
):
author
=
ForeignKey
(
Author
,
CASCADE
)
class
Meta
:
app_label
=
'schema'
# Create the table and one referring it.
with
connection
.
schema_editor
()
as
editor
:
with
connection
.
schema_editor
()
as
editor
:
editor
.
create_model
(
Author
)
editor
.
create_model
(
Author
)
editor
.
create_model
(
Book
)
# Ensure the table is there to begin with
# Ensure the table is there to begin with
columns
=
self
.
column_classes
(
Author
)
columns
=
self
.
column_classes
(
Author
)
self
.
assertEqual
(
columns
[
'name'
][
0
],
"CharField"
)
self
.
assertEqual
(
columns
[
'name'
][
0
],
"CharField"
)
# Alter the table
# Alter the table
with
connection
.
schema_editor
()
as
editor
:
with
connection
.
schema_editor
(
atomic
=
connection
.
features
.
supports_atomic_references_rename
)
as
editor
:
editor
.
alter_db_table
(
Author
,
"schema_author"
,
"schema_otherauthor"
)
editor
.
alter_db_table
(
Author
,
"schema_author"
,
"schema_otherauthor"
)
# Ensure the table is there afterwards
# Ensure the table is there afterwards
Author
.
_meta
.
db_table
=
"schema_otherauthor"
Author
.
_meta
.
db_table
=
"schema_otherauthor"
columns
=
self
.
column_classes
(
Author
)
columns
=
self
.
column_classes
(
Author
)
self
.
assertEqual
(
columns
[
'name'
][
0
],
"CharField"
)
self
.
assertEqual
(
columns
[
'name'
][
0
],
"CharField"
)
# Ensure the foreign key reference was updated
self
.
assertForeignKeyExists
(
Book
,
"author_id"
,
"schema_otherauthor"
)
# Alter the table again
# Alter the table again
with
connection
.
schema_editor
()
as
editor
:
with
connection
.
schema_editor
(
atomic
=
connection
.
features
.
supports_atomic_references_rename
)
as
editor
:
editor
.
alter_db_table
(
Author
,
"schema_otherauthor"
,
"schema_author"
)
editor
.
alter_db_table
(
Author
,
"schema_otherauthor"
,
"schema_author"
)
# Ensure the table is still there
# Ensure the table is still there
Author
.
_meta
.
db_table
=
"schema_author"
Author
.
_meta
.
db_table
=
"schema_author"
...
...
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