Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions ckanext/datastore/backend/postgres.py
Original file line number Diff line number Diff line change
Expand Up @@ -934,6 +934,29 @@ def create_table(context, data_dict, plugin_data):
sql_fields = u", ".join([u'{0} {1}'.format(
identifier(f['id']), f['type']) for f in fields])

# (canada fork only): foreign keys
# TODO: upstream contrib!!
foreign_keys = data_dict.get('foreign_keys')
foreign_fields = []
if foreign_keys:
for f_table_name, column_name_map in foreign_keys.items():
fk_counter = 1
for p_column_name, f_column_name in column_name_map.items():
log.debug('Trying to build foreign key constraint for {0}.{1} on column {2}'.format(
f_table_name,
f_table_name,
p_column_name
))
foreign_fields.append('CONSTRAINT {0} FOREIGN KEY ({1}) REFERENCES {2}({3})'.format(
identifier('fk_%s_%s' % (f_table_name, fk_counter)),
identifier(p_column_name),
identifier(f_table_name),
identifier(f_column_name)
))
fk_counter += 1
if foreign_fields:
sql_fields += ", %s" % ", ".join(foreign_fields)

sql_string = u'CREATE TABLE {0} ({1});'.format(
identifier(data_dict['resource_id']),
sql_fields
Expand Down Expand Up @@ -1025,6 +1048,27 @@ def alter_table(context, data_dict, plugin_data):
identifier(f['id']),
f['type']))

# (canada fork only): foreign keys
# TODO: upstream contrib!!
foreign_keys = data_dict.get('foreign_keys')
if foreign_keys:
for f_table_name, column_name_map in foreign_keys.items():
fk_counter = 1
for p_column_name, f_column_name in column_name_map.items():
log.debug('Trying to build foreign key constraint for {0}.{1} on column {2}'.format(
f_table_name,
f_table_name,
p_column_name
))
alter_sql.append('ALTER TABLE {0} ADD CONSTRAINT {1} FOREIGN KEY ({2}) REFERENCES {3}({4})'.format(
identifier(data_dict['resource_id']),
identifier('fk_%s_%s' % (f_table_name, fk_counter)),
identifier(p_column_name),
identifier(f_table_name),
identifier(f_column_name)
))
fk_counter += 1

if plugin_data or any('info' in f for f in supplied_fields):
raw_field_info, _old = _get_raw_field_info(
context['connection'],
Expand Down
3 changes: 3 additions & 0 deletions ckanext/datastore/logic/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ def datastore_create(context, data_dict):
:type records: list of dictionaries
:param primary_key: fields that represent a unique key (optional)
:type primary_key: list or comma separated string
:param foreign_keys: tables and fields that represent foreign keys (optional)
:type foreign_keys: dict of table names and field ids, e.g. {'table_name':
['field_id1', 'field_id2']}
:param indexes: indexes on table (optional)
:type indexes: list or comma separated string
:param triggers: trigger functions to apply to this table on update/insert.
Expand Down
3 changes: 3 additions & 0 deletions ckanext/datastore/logic/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ def datastore_create_schema():
'info': [ignore_missing],
},
'primary_key': [ignore_missing, list_of_strings_or_string],
# (canada fork only): foreign_keys
# TODO: upstream contrib!!
'foreign_keys': [ignore_missing, dict_only],
'indexes': [ignore_missing, list_of_strings_or_string],
'triggers': {
'when': [
Expand Down