1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-04-14 09:08:32 +00:00

Resolve "If a table has a link row field it is not possible to change the table name"

This commit is contained in:
Bram Wiepjes 2020-09-02 19:23:45 +00:00
parent c98fec874b
commit 328e7b35e7
9 changed files with 72 additions and 32 deletions
README.md
backend
setup.py
src/baserow
config/settings
contrib/database
tests/baserow/contrib/database
changelog.md
web-frontend

View file

@ -106,7 +106,7 @@ Created by Bram Wiepjes (Baserow) - bram@baserow.io.
Distributes under the MIT license. See `LICENSE` for more information.
Version: 0.3.0
Version: 0.3.1
The official repository can be found at https://gitlab.com/bramw/baserow.

View file

@ -6,7 +6,7 @@ from setuptools import find_packages, setup
PROJECT_DIR = os.path.dirname(__file__)
REQUIREMENTS_DIR = os.path.join(PROJECT_DIR, 'requirements')
VERSION = '0.3.0'
VERSION = '0.3.1'
def get_requirements(env):

View file

@ -153,7 +153,7 @@ SPECTACULAR_SETTINGS = {
'name': 'MIT',
'url': 'https://gitlab.com/bramw/baserow/-/blob/master/LICENSE'
},
'VERSION': '0.3.0',
'VERSION': '0.3.1',
'SERVE_INCLUDE_SCHEMA': False,
'TAGS': [
{'name': 'User'},

View file

@ -0,0 +1,58 @@
# There was a bug where if table contained a link row field and the user changes the
# name of the table it would crash. This was because the name of the foreignkey columns
# was related to the name of the table. The name of now based on the id of the table
# which makes it of course more robust. This migration checks all the through tables to
# see if some names are incorrect and if so they will be corrected.
from django.db import migrations, connections
from django.conf import settings
def rename_sql(schema_editor, table, old_name, new_name):
return schema_editor.sql_rename_column % {
"table": schema_editor.quote_name(table),
"old_column": schema_editor.quote_name(old_name),
"new_column": schema_editor.quote_name(new_name),
"type": None,
}
def forward(apps, schema_editor):
LinkRowField = apps.get_model('database', 'LinkRowField')
connection = connections[settings.USER_TABLE_DATABASE]
cursor = connection.cursor()
with connection.schema_editor() as tables_schema_editor:
for field in LinkRowField.objects.all():
table_name = f'database_relation_{field.link_row_relation_id}'
new_name = f'table{field.table.id}model_id'
first = field.id < field.link_row_related_field.id
cursor.execute("SELECT column_name FROM information_schema.columns WHERE "
"table_name = %s", [table_name])
rows = cursor.fetchall()
# Because it is a through table we expect exactly 3 columns, the id,
# foreignkey 1 and foreignkey 2.
if len(rows) != 3:
continue
# Because the first column is always the first created link row field we
# which column is related to the field object.
old_name = rows[1][0] if first else rows[2][0]
if old_name != new_name:
tables_schema_editor.execute(
rename_sql(tables_schema_editor, table_name, old_name, new_name)
)
class Migration(migrations.Migration):
dependencies = [
('database', '0010_auto_20200828_1306'),
]
operations = [
migrations.RunPython(forward, migrations.RunPython.noop),
]

View file

@ -1,7 +1,6 @@
from django.db import models
from baserow.core.mixins import OrderableMixin
from baserow.core.utils import to_pascal_case, remove_special_characters
from baserow.contrib.database.fields.registries import field_type_registry
@ -79,23 +78,6 @@ class Table(OrderableMixin, models.Model):
queryset = Table.objects.filter(database=database)
return cls.get_highest_order_of_queryset(queryset) + 1
@property
def model_class_name(self):
"""
Generates a pascal case based class name based on the table name.
:return: The generated model class name.
:rtype: str
"""
name = remove_special_characters(self.name, False)
name = to_pascal_case(name)
if name[0].isnumeric():
name = f'Table{name}'
return name
def get_model(self, fields=None, field_ids=None, attribute_names=False,
manytomany_models=None):
"""
@ -203,7 +185,7 @@ class Table(OrderableMixin, models.Model):
# Create the model class.
model = type(
str(f'{self.model_class_name}TableModel'),
str(f'Table{self.pk}Model'),
(models.Model,),
attrs
)

View file

@ -220,6 +220,12 @@ def test_link_row_field_type_rows(data_fixture):
f'field_{link_row_field.id}': [customers_row_1.id],
})
example_table.name = 'Example2'
example_table.save()
customers_table.name = 'Customers2'
customers_table.save()
row_1_all = getattr(row, f'field_{link_row_field.id}').all()
row_2_all = getattr(row_2, f'field_{link_row_field.id}').all()
row_1_ids = [i.id for i in row_1_all]

View file

@ -19,15 +19,6 @@ def test_group_user_get_next_order(data_fixture):
assert Table.get_last_order(database_2) == 11
@pytest.mark.django_db
def test_model_class_name(data_fixture):
table_1 = data_fixture.create_database_table(name='Some test table')
assert table_1.model_class_name == 'SomeTestTable'
table_2 = data_fixture.create_database_table(name='3 Some test @ table')
assert table_2.model_class_name == 'Table3SomeTestTable'
@pytest.mark.django_db
def test_get_table_model(data_fixture):
table = data_fixture.create_database_table(name='Cars')
@ -39,6 +30,7 @@ def test_get_table_model(data_fixture):
name='For sale')
model = table.get_model(attribute_names=True)
assert model.__name__ == f'Table{table.id}Model'
assert model._generated_table_model
assert model._meta.db_table == f'database_table_{table.id}'
assert len(model._meta.get_fields()) == 4

View file

@ -3,6 +3,8 @@
## Unreleased
* Added contribution guidelines.
* Fixed bug where it was not possible to change the table name when it contained a link
row field.
## Released (2020-08-31)

View file

@ -1,6 +1,6 @@
{
"name": "baserow",
"version": "0.3.0",
"version": "0.3.1",
"private": true,
"description": "Baserow: open source online database web frontend.",
"author": "Bram Wiepjes (Baserow)",