Add specific data type options for new table entry form
including basic FK / relationship support
This commit is contained in:
parent
98fa6eea05
commit
e4c2336659
|
@ -118,7 +118,7 @@
|
||||||
v-slot="props"
|
v-slot="props"
|
||||||
% endif
|
% endif
|
||||||
>
|
>
|
||||||
{{ props.row.data_type }}
|
{{ formatDataType(props.row.data_type) }}
|
||||||
</b-table-column>
|
</b-table-column>
|
||||||
|
|
||||||
<b-table-column field="nullable"
|
<b-table-column field="nullable"
|
||||||
|
@ -196,26 +196,89 @@
|
||||||
</b-input>
|
</b-input>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field label="Data Type">
|
<b-field grouped>
|
||||||
<b-input v-model="editingColumnDataType"></b-input>
|
|
||||||
|
<b-field label="Data Type">
|
||||||
|
<b-select v-model="editingColumnDataType">
|
||||||
|
<option value="String">String</option>
|
||||||
|
<option value="Boolean">Boolean</option>
|
||||||
|
<option value="Integer">Integer</option>
|
||||||
|
<option value="Numeric">Numeric</option>
|
||||||
|
<option value="Date">Date</option>
|
||||||
|
<option value="DateTime">DateTime</option>
|
||||||
|
<option value="Text">Text</option>
|
||||||
|
<option value="_fk_uuid_">FK/UUID</option>
|
||||||
|
<option value="_other_">Other</option>
|
||||||
|
</b-select>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field v-if="editingColumnDataType == 'String'"
|
||||||
|
label="Length"
|
||||||
|
:type="{'is-danger': !editingColumnDataTypeLength}"
|
||||||
|
style="max-width: 6rem;">
|
||||||
|
<b-input v-model="editingColumnDataTypeLength">
|
||||||
|
</b-input>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field v-if="editingColumnDataType == 'Numeric'"
|
||||||
|
label="Precision"
|
||||||
|
:type="{'is-danger': !editingColumnDataTypePrecision}"
|
||||||
|
style="max-width: 6rem;">
|
||||||
|
<b-input v-model="editingColumnDataTypePrecision">
|
||||||
|
</b-input>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field v-if="editingColumnDataType == 'Numeric'"
|
||||||
|
label="Scale"
|
||||||
|
:type="{'is-danger': !editingColumnDataTypeScale}"
|
||||||
|
style="max-width: 6rem;">
|
||||||
|
<b-input v-model="editingColumnDataTypeScale">
|
||||||
|
</b-input>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field v-if="editingColumnDataType == '_fk_uuid_'"
|
||||||
|
label="Reference Table"
|
||||||
|
:type="{'is-danger': !editingColumnDataTypeReference}">
|
||||||
|
<b-select v-model="editingColumnDataTypeReference">
|
||||||
|
<option v-for="table in existingTables"
|
||||||
|
:key="table.name"
|
||||||
|
:value="table.name">
|
||||||
|
{{ table.name }}
|
||||||
|
</option>
|
||||||
|
</b-select>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<b-field v-if="editingColumnDataType == '_other_'"
|
||||||
|
label="Literal (include parens!)"
|
||||||
|
:type="{'is-danger': !editingColumnDataTypeLiteral}"
|
||||||
|
expanded>
|
||||||
|
<b-input v-model="editingColumnDataTypeLiteral">
|
||||||
|
</b-input>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field grouped>
|
<b-field grouped>
|
||||||
|
|
||||||
<b-field label="Nullable">
|
<b-field label="Nullable">
|
||||||
<b-checkbox v-model="editingColumnNullable"
|
<b-checkbox v-model="editingColumnNullable"
|
||||||
native-value="true">
|
native-value="true">
|
||||||
{{ editingColumnNullable }}
|
{{ editingColumnNullable }}
|
||||||
</b-checkbox>
|
</b-checkbox>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
<b-field label="Versioned"
|
<b-field label="Versioned"
|
||||||
v-if="tableVersioned">
|
v-if="tableVersioned">
|
||||||
<b-checkbox v-model="editingColumnVersioned"
|
<b-checkbox v-model="editingColumnVersioned"
|
||||||
native-value="true">
|
native-value="true">
|
||||||
{{ editingColumnVersioned }}
|
{{ editingColumnVersioned }}
|
||||||
</b-checkbox>
|
</b-checkbox>
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
|
<b-field v-if="editingColumnDataType == '_fk_uuid_'"
|
||||||
|
label="Relationship">
|
||||||
|
<b-input v-model="editingColumnRelationship"></b-input>
|
||||||
|
</b-field>
|
||||||
|
|
||||||
</b-field>
|
</b-field>
|
||||||
|
|
||||||
|
@ -638,6 +701,8 @@
|
||||||
ThisPageData.activeStep = null
|
ThisPageData.activeStep = null
|
||||||
ThisPageData.alembicBranchOptions = ${json.dumps(branch_name_options)|n}
|
ThisPageData.alembicBranchOptions = ${json.dumps(branch_name_options)|n}
|
||||||
|
|
||||||
|
ThisPageData.existingTables = ${json.dumps(existing_tables)|n}
|
||||||
|
|
||||||
ThisPageData.alembicBranch = ${json.dumps(branch_name)|n}
|
ThisPageData.alembicBranch = ${json.dumps(branch_name)|n}
|
||||||
ThisPageData.tableName = '${rattail_app.get_table_prefix()}_widget'
|
ThisPageData.tableName = '${rattail_app.get_table_prefix()}_widget'
|
||||||
ThisPageData.tableModelName = '${rattail_app.get_class_prefix()}Widget'
|
ThisPageData.tableModelName = '${rattail_app.get_class_prefix()}Widget'
|
||||||
|
@ -648,7 +713,10 @@
|
||||||
|
|
||||||
ThisPageData.tableColumns = [{
|
ThisPageData.tableColumns = [{
|
||||||
name: 'uuid',
|
name: 'uuid',
|
||||||
data_type: 'String(length=32)',
|
data_type: {
|
||||||
|
type: 'String',
|
||||||
|
length: 32,
|
||||||
|
},
|
||||||
nullable: false,
|
nullable: false,
|
||||||
description: "UUID primary key",
|
description: "UUID primary key",
|
||||||
versioned: true,
|
versioned: true,
|
||||||
|
@ -658,17 +726,29 @@
|
||||||
ThisPageData.editingColumn = null
|
ThisPageData.editingColumn = null
|
||||||
ThisPageData.editingColumnName = null
|
ThisPageData.editingColumnName = null
|
||||||
ThisPageData.editingColumnDataType = null
|
ThisPageData.editingColumnDataType = null
|
||||||
|
ThisPageData.editingColumnDataTypeLength = null
|
||||||
|
ThisPageData.editingColumnDataTypePrecision = null
|
||||||
|
ThisPageData.editingColumnDataTypeScale = null
|
||||||
|
ThisPageData.editingColumnDataTypeReference = null
|
||||||
|
ThisPageData.editingColumnDataTypeLiteral = null
|
||||||
ThisPageData.editingColumnNullable = true
|
ThisPageData.editingColumnNullable = true
|
||||||
ThisPageData.editingColumnDescription = null
|
ThisPageData.editingColumnDescription = null
|
||||||
ThisPageData.editingColumnVersioned = true
|
ThisPageData.editingColumnVersioned = true
|
||||||
|
ThisPageData.editingColumnRelationship = null
|
||||||
|
|
||||||
ThisPage.methods.tableAddColumn = function() {
|
ThisPage.methods.tableAddColumn = function() {
|
||||||
this.editingColumn = null
|
this.editingColumn = null
|
||||||
this.editingColumnName = null
|
this.editingColumnName = null
|
||||||
this.editingColumnDataType = null
|
this.editingColumnDataType = null
|
||||||
|
this.editingColumnDataTypeLength = null
|
||||||
|
this.editingColumnDataTypePrecision = null
|
||||||
|
this.editingColumnDataTypeScale = null
|
||||||
|
this.editingColumnDataTypeReference = null
|
||||||
|
this.editingColumnDataTypeLiteral = null
|
||||||
this.editingColumnNullable = true
|
this.editingColumnNullable = true
|
||||||
this.editingColumnDescription = null
|
this.editingColumnDescription = null
|
||||||
this.editingColumnVersioned = true
|
this.editingColumnVersioned = true
|
||||||
|
this.editingColumnRelationship = null
|
||||||
this.editingColumnShowDialog = true
|
this.editingColumnShowDialog = true
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.editingColumnName.focus()
|
this.$refs.editingColumnName.focus()
|
||||||
|
@ -678,16 +758,43 @@
|
||||||
ThisPage.methods.tableEditColumn = function(column) {
|
ThisPage.methods.tableEditColumn = function(column) {
|
||||||
this.editingColumn = column
|
this.editingColumn = column
|
||||||
this.editingColumnName = column.name
|
this.editingColumnName = column.name
|
||||||
this.editingColumnDataType = column.data_type
|
this.editingColumnDataType = column.data_type.type
|
||||||
|
this.editingColumnDataTypeLength = column.data_type.length
|
||||||
|
this.editingColumnDataTypePrecision = column.data_type.precision
|
||||||
|
this.editingColumnDataTypeScale = column.data_type.scale
|
||||||
|
this.editingColumnDataTypeReference = column.data_type.reference
|
||||||
|
this.editingColumnDataTypeLiteral = column.data_type.literal
|
||||||
this.editingColumnNullable = column.nullable
|
this.editingColumnNullable = column.nullable
|
||||||
this.editingColumnDescription = column.description
|
this.editingColumnDescription = column.description
|
||||||
this.editingColumnVersioned = column.versioned
|
this.editingColumnVersioned = column.versioned
|
||||||
|
this.editingColumnRelationship = column.relationship
|
||||||
this.editingColumnShowDialog = true
|
this.editingColumnShowDialog = true
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$refs.editingColumnName.focus()
|
this.$refs.editingColumnName.focus()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ThisPage.methods.formatDataType = function(dataType) {
|
||||||
|
if (dataType.type == 'String') {
|
||||||
|
return `sa.String(length=${'$'}{dataType.length})`
|
||||||
|
} else if (dataType.type == 'Numeric') {
|
||||||
|
return `sa.Numeric(precision=${'$'}{dataType.precision}, scale=${'$'}{dataType.scale})`
|
||||||
|
} else if (dataType.type == '_fk_uuid_') {
|
||||||
|
return 'sa.String(length=32)'
|
||||||
|
} else if (dataType.type == '_other_') {
|
||||||
|
return dataType.literal
|
||||||
|
} else {
|
||||||
|
return `sa.${'$'}{dataType.type}()`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ThisPage.watch.editingColumnDataTypeReference = function(newval, oldval) {
|
||||||
|
this.editingColumnRelationship = newval
|
||||||
|
if (newval && !this.editingColumnName) {
|
||||||
|
this.editingColumnName = `${'$'}{newval}_uuid`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ThisPage.methods.editingColumnSave = function() {
|
ThisPage.methods.editingColumnSave = function() {
|
||||||
let column
|
let column
|
||||||
if (this.editingColumn) {
|
if (this.editingColumn) {
|
||||||
|
@ -698,10 +805,24 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
column.name = this.editingColumnName
|
column.name = this.editingColumnName
|
||||||
column.data_type = this.editingColumnDataType
|
|
||||||
|
let dataType = {type: this.editingColumnDataType}
|
||||||
|
if (dataType.type == 'String') {
|
||||||
|
dataType.length = this.editingColumnDataTypeLength
|
||||||
|
} else if (dataType.type == 'Numeric') {
|
||||||
|
dataType.precision = this.editingColumnDataTypePrecision
|
||||||
|
dataType.scale = this.editingColumnDataTypeScale
|
||||||
|
} else if (dataType.type == '_fk_uuid_') {
|
||||||
|
dataType.reference = this.editingColumnDataTypeReference
|
||||||
|
} else if (dataType.type == '_other_') {
|
||||||
|
dataType.literal = this.editingColumnDataTypeLiteral
|
||||||
|
}
|
||||||
|
column.data_type = dataType
|
||||||
|
|
||||||
column.nullable = this.editingColumnNullable
|
column.nullable = this.editingColumnNullable
|
||||||
column.description = this.editingColumnDescription
|
column.description = this.editingColumnDescription
|
||||||
column.versioned = this.editingColumnVersioned
|
column.versioned = this.editingColumnVersioned
|
||||||
|
column.relationship = this.editingColumnRelationship
|
||||||
|
|
||||||
this.editingColumnShowDialog = false
|
this.editingColumnShowDialog = false
|
||||||
}
|
}
|
||||||
|
@ -724,6 +845,10 @@
|
||||||
this.modelImportStatus = "import not yet attempted"
|
this.modelImportStatus = "import not yet attempted"
|
||||||
this.modelImportProblem = false
|
this.modelImportProblem = false
|
||||||
|
|
||||||
|
for (let column of this.tableColumns) {
|
||||||
|
column.formatted_data_type = this.formatDataType(column.data_type)
|
||||||
|
}
|
||||||
|
|
||||||
let url = '${url('{}.write_model_file'.format(route_prefix))}'
|
let url = '${url('{}.write_model_file'.format(route_prefix))}'
|
||||||
let params = {
|
let params = {
|
||||||
branch_name: this.alembicBranch,
|
branch_name: this.alembicBranch,
|
||||||
|
|
|
@ -31,6 +31,7 @@ import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
from sqlalchemy_utils import get_mapper
|
||||||
|
|
||||||
from rattail.util import simple_error
|
from rattail.util import simple_error
|
||||||
|
|
||||||
|
@ -122,8 +123,6 @@ class TableView(MasterView):
|
||||||
f.remove('versioned')
|
f.remove('versioned')
|
||||||
|
|
||||||
def get_instance(self):
|
def get_instance(self):
|
||||||
from sqlalchemy_utils import get_mapper
|
|
||||||
|
|
||||||
model = self.model
|
model = self.model
|
||||||
table_name = self.request.matchdict['table_name']
|
table_name = self.request.matchdict['table_name']
|
||||||
|
|
||||||
|
@ -204,6 +203,9 @@ class TableView(MasterView):
|
||||||
branch_name = None
|
branch_name = None
|
||||||
kwargs['branch_name'] = branch_name
|
kwargs['branch_name'] = branch_name
|
||||||
|
|
||||||
|
kwargs['existing_tables'] = [{'name': table.name}
|
||||||
|
for table in model.Base.metadata.sorted_tables]
|
||||||
|
|
||||||
kwargs['model_dir'] = (os.path.dirname(model.__file__)
|
kwargs['model_dir'] = (os.path.dirname(model.__file__)
|
||||||
+ os.sep)
|
+ os.sep)
|
||||||
|
|
||||||
|
@ -212,6 +214,7 @@ class TableView(MasterView):
|
||||||
def write_model_file(self):
|
def write_model_file(self):
|
||||||
data = self.request.json_body
|
data = self.request.json_body
|
||||||
path = data['module_file']
|
path = data['module_file']
|
||||||
|
model = self.model
|
||||||
|
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
if data['overwrite']:
|
if data['overwrite']:
|
||||||
|
@ -219,6 +222,23 @@ class TableView(MasterView):
|
||||||
else:
|
else:
|
||||||
return {'error': "File already exists"}
|
return {'error': "File already exists"}
|
||||||
|
|
||||||
|
for column in data['columns']:
|
||||||
|
if column['data_type']['type'] == '_fk_uuid_' and column['relationship']:
|
||||||
|
name = column['relationship']
|
||||||
|
|
||||||
|
table = model.Base.metadata.tables[column['data_type']['reference']]
|
||||||
|
try:
|
||||||
|
mapper = get_mapper(table)
|
||||||
|
except ValueError:
|
||||||
|
reference_model = table.name.capitalize()
|
||||||
|
else:
|
||||||
|
reference_model = mapper.class_.__name__
|
||||||
|
|
||||||
|
column['relationship'] = {
|
||||||
|
'name': name,
|
||||||
|
'reference_model': reference_model,
|
||||||
|
}
|
||||||
|
|
||||||
self.db_handler.write_table_model(data, path)
|
self.db_handler.write_table_model(data, path)
|
||||||
return {'ok': True}
|
return {'ok': True}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue