Commit 40b112a1 authored by Anze Vavpetic's avatar Anze Vavpetic
Browse files

added db to aleph converter

parent f0462cb1
......@@ -24,6 +24,11 @@ class DBContext:
cursor.execute("SELECT column_name FROM information_schema.columns WHERE table_name = '%s'" % table)
self.cols[table] = [col for (col,) in cursor]
self.all_cols = dict(self.cols)
self.col_vals = {}
for table, cols in self.cols.items():
for col in cols:
cursor.execute("SELECT DISTINCT %s FROM %s" % (col, table))
self.col_vals[col] = [val for (val,) in cursor]
self.connected = {}
cursor.execute(
"SELECT table_name, column_name, referenced_table_name, referenced_column_name \
......@@ -43,12 +48,14 @@ class DBContext:
self.pkeys[table] = pk
self.target_table = self.tables[0]
self.target_att = None
self.target_att_val = None
con.close()
def update(self, postdata):
widget_id = postdata.get('widget_id')[0]
self.target_table = postdata.get('target_table%s' % widget_id)[0]
self.target_att = postdata.get('target_att%s' % widget_id)[0]
self.target_att_val = postdata.get('target_att_val%s' % widget_id)[0]
self.tables = postdata.get('tables%s' % widget_id, [])
# Propagate the selected tables
for table in self.cols.keys():
......@@ -61,9 +68,6 @@ class DBContext:
for table in self.tables:
self.cols[table] = postdata.get('%s_columns%s' % (table, widget_id), [])
import cPickle
cPickle.dump(self, open('context_example.pkl', 'w'))
def __repr__(self):
return str((self.target_table, self.target_att, self.tables, self.cols, self.connected))
......@@ -24,34 +24,18 @@ class ILP_DBContext:
self.cursor.execute("SELECT %s FROM %s" % (','.join(cols), table))
return [cols for cols in self.cursor]
class RSD_DBContext(ILP_DBContext):
'''
Converts the database context to RSD inputs.
'''
def all_examples(self):
target = self.db.target_table
examples = self.rows(target, [self.db.target_att, self.db.pkeys[target]])
return '\n'.join(['%s(%s, %s).' % (target, cls, pk) for cls, pk in examples])
def background_knowledge(self):
modeslist, getters = [self.mode(self.db.target_table, [('+', self.db.target_table)], head=True)], []
for (table, ref_table) in self.db.connected.keys():
if ref_table == self.db.target_table:
continue # Skip backward connections
modeslist.append(self.mode('has_%s' % ref_table, [('+', table), ('-', ref_table)]))
getters.extend(self.connecting_clause(table, ref_table))
for table, atts in self.db.cols.items():
for att in atts:
if att == self.db.target_att and table == self.db.target_table or \
att in self.db.fkeys[table] or att == self.db.pkeys[table]:
continue
modeslist.append(self.mode('%s_%s' % (table, att), [('+', table), ('-', att)]))
modeslist.append(self.mode('instantiate', [('+', att)]))
getters.extend(self.attribute_clause(table, att))
return '\n'.join(self.db_connection() + modeslist + getters + self.user_settings())
def user_settings(self):
return [':- set(%s,%s).' % (key,val) for key, val in self.settings.items()]
def mode(self, predicate, args, recall=1, head=False):
return ':- mode%s(%d, %s(%s)).' % ('h' if head else 'b', recall, predicate, ','.join([t+arg for t,arg in args]))
return ':- mode%s(%s, %s(%s)).' % ('h' if head else 'b', str(recall), predicate, ','.join([t+arg for t,arg in args]))
def db_connection(self):
con = self.db.connection
host, db, user, pwd = con.host, con.database, con.user, con.password
return [':- use_module(library(myddas)).', \
':- db_open(mysql, \'%s\'/\'%s\', \'%s\', \'%s\').' % (host, db, user, pwd)] + \
[':- db_import(%s, %s).' % (table, table) for table in self.db.tables]
def connecting_clause(self, table, ref_table):
var_table, var_ref_table = table.capitalize(), ref_table.capitalize()
......@@ -79,29 +63,103 @@ class RSD_DBContext(ILP_DBContext):
return ['%s_%s(%s, %s) :-' % (table, att, var_table, var_att),
'\t%s(%s).' % (table, ','.join([att.capitalize() if att!=pk else var_table for att in self.db.cols[table]]))]
def db_connection(self):
con = self.db.connection
host, db, user, pwd = con.host, con.database, con.user, con.password
return [':- use_module(library(myddas)).', \
':- db_open(mysql, \'%s\'/\'%s\', \'%s\', \'%s\').' % (host, db, user, pwd)] + \
[':- db_import(%s, %s).' % (table, table) for table in self.db.tables]
class RSD_DBContext(ILP_DBContext):
'''
Converts the database context to RSD inputs.
'''
def all_examples(self):
target = self.db.target_table
examples = self.rows(target, [self.db.target_att, self.db.pkeys[target]])
return '\n'.join(['%s(%s, %s).' % (target, cls, pk) for cls, pk in examples])
def user_settings(self):
return [':- set(%s,%s).' % (key,val) for key, val in self.settings.items()]
def background_knowledge(self):
modeslist, getters = [self.mode(self.db.target_table, [('+', self.db.target_table)], head=True)], []
for (table, ref_table) in self.db.connected.keys():
if ref_table == self.db.target_table:
continue # Skip backward connections
modeslist.append(self.mode('has_%s' % ref_table, [('+', table), ('-', ref_table)]))
getters.extend(self.connecting_clause(table, ref_table))
for table, atts in self.db.cols.items():
for att in atts:
if att == self.db.target_att and table == self.db.target_table or \
att in self.db.fkeys[table] or att == self.db.pkeys[table]:
continue
modeslist.append(self.mode('%s_%s' % (table, att), [('+', table), ('-', att)]))
modeslist.append(self.mode('instantiate', [('+', att)]))
getters.extend(self.attribute_clause(table, att))
return '\n'.join(self.db_connection() + modeslist + getters + self.user_settings())
class Aleph_DBContext(ILP_DBContext):
'''
Converts the database context to Aleph inputs.
TODO.
'''
def __init__(self, *args, **kwargs):
ILP_DBContext.__init__(self, *args, **kwargs)
self.__pos_examples, self.__neg_examples = None, None
def __examples(self):
if not (self.__pos_examples and self.__neg_examples):
target, att, target_val = self.db.target_table, self.db.target_att, self.db.target_att_val
rows = self.rows(target, [att, self.db.pkeys[target]])
pos_rows, neg_rows = [], []
for row in rows:
if row[0] == target_val:
pos_rows.append(row)
else:
neg_rows.append(row)
self.__pos_examples = '\n'.join(['%s(%s).' % (target_val, id) for _, id in pos_rows])
self.__neg_examples = '\n'.join(['%s(%s).' % (target_val, id) for _, id in neg_rows])
return self.__pos_examples, self.__neg_examples
def positive_examples(self):
pass
return self.__examples()[0]
def negative_examples(self):
pass
return self.__examples()[1]
def background_knowledge(self):
pass
modeslist, getters = [self.mode(self.db.target_att_val, [('+', self.db.target_table)], head=True)], []
determinations, types = [], []
for (table, ref_table) in self.db.connected.keys():
if ref_table == self.db.target_table:
continue # Skip backward connections
modeslist.append(self.mode('has_%s' % ref_table, [('+', table), ('-', ref_table)], recall='*'))
determinations.append(':- determination(%s/1, has_%s/2).' % (self.db.target_att_val, ref_table))
types.extend(self.concept_type_def(table))
types.extend(self.concept_type_def(ref_table))
getters.extend(self.connecting_clause(table, ref_table))
for table, atts in self.db.cols.items():
for att in atts:
if att == self.db.target_att and table == self.db.target_table or \
att in self.db.fkeys[table] or att == self.db.pkeys[table]:
continue
modeslist.append(self.mode('%s_%s' % (table, att), [('+', table), ('#', att)], recall='*'))
determinations.append(':- determination(%s/1, %s_%s/2).' % (self.db.target_att_val, table, att))
types.extend(self.constant_type_def(table, att))
getters.extend(self.attribute_clause(table, att))
return '\n'.join(self.db_connection() + self.user_settings() + modeslist + determinations + types + getters)
def concept_type_def(self, table):
return ['%s(%s).' % (table, id) for (id,) in self.rows(table, [self.db.pkeys[table]])]
# var_pk = self.db.pkeys[table].capitalize()
# variables = ','.join([var_pk if col.capitalize() == var_pk else '_' for col in self.db.cols[table]])
# return ['%s(%s) :-' % (table, var_pk),
# '\t%s(%s).' % (table, variables)]
def constant_type_def(self, table, att):
return ['%s(%s).' % (att, val) for val in self.db.col_vals[att]]
# var_att = att.capitalize()
# variables = ','.join([var_att if col == att else '_' for col in self.db.cols[table]])
# return ['%s(%s) :-' % (att, var_att),
# '\t%s(%s).' % (table, variables)]
def connecting_clause(self, table, ref_table):
pk, fk = self.db.pkeys[ref_table], self.db.connected[(ref_table, table)][0]
return ['has_%s(%s,%s).' % (ref_table,id,ref_id) for (id, ref_id) in self.rows(ref_table, [pk, fk])]
def attribute_clause(self, table, att):
pk = self.db.pkeys[table]
return ['%s_%s(%s, %s).' % (table, att, id, val) for (id, val) in self.rows(table, [pk, att])]
if __name__ == '__main__':
from context import DBConnection, DBContext
......@@ -109,16 +167,12 @@ if __name__ == '__main__':
context = DBContext(DBConnection('root','','localhost','test'))
context.target_table = 'trains'
context.target_att = 'direction'
context.target_att_val = 'east'
rsd = RSD_DBContext(context)
ex, bk = rsd.all_examples(), rsd.background_knowledge()
print ex
print bk
f = open('trains_mysql.pl','w')
f.write(ex)
f.close()
f = open('trains_mysql.b','w')
f.write(bk)
f.close()
\ No newline at end of file
aleph = Aleph_DBContext(context)
print aleph.positive_examples()
print aleph.negative_examples()
print aleph.background_knowledge()
\ No newline at end of file
......@@ -11,5 +11,7 @@ def mysql_db_context(request, input_dict, output_dict, widget):
con = input_dict['connection']
initial_context = DBContext(con)
initial_target_cols = initial_context.cols[initial_context.target_table]
initial_target_col_vals = initial_context.col_vals[initial_target_cols[0]]
cols_dump = json.dumps(initial_context.cols)
return render(request, 'interactions/db_context.html', {'widget':widget, 'context': initial_context, 'target_cols' : initial_target_cols, 'cols' : cols_dump})
col_vals_dump = json.dumps(initial_context.col_vals)
return render(request, 'interactions/db_context.html', {'widget':widget, 'context': initial_context, 'target_cols' : initial_target_cols, 'cols' : cols_dump, 'col_vals' : col_vals_dump, 'target_col_vals' : initial_target_col_vals})
......@@ -13,6 +13,12 @@
<option value="{{col}}" {% if forloop.first %}selected="selected"{% endif %}>{{col}}</option>
{% endfor %}
</select>
<label>Target attribute value:</label>
<select name="target_att_val{{widget.pk}}">
{% for val in target_col_vals %}
<option value="{{val}}" {% if forloop.first %}selected="selected"{% endif %}>{{val}}</option>
{% endfor %}
</select>
<label>Select tables to be used:</label>
<select multiple name="tables{{widget.pk}}">
{% for table in context.tables %}
......@@ -43,6 +49,7 @@
<script type="text/javascript">
// Columns data.
var cols = {{cols|safe}};
var col_vals = {{col_vals|safe}};
$('select[name="target_table{{widget.pk}}"]').change(function () {
var selected_table = $(this).first('option:selected').val();
var available_cols = cols[selected_table];
......@@ -54,6 +61,17 @@
att_select.append($('<option></option>').attr('value', col).text(col));
}
});
$('select[name="target_att{{widget.pk}}"]').change(function () {
var selected_att = $(this).first('option:selected').val();
var available_vals = col_vals[selected_att];
// Change the list of options as the target attribute
var val_select = $('select[name="target_att_val{{widget.pk}}"]');
val_select.empty();
for (idx in available_vals) {
var col = available_vals[idx];
val_select.append($('<option></option>').attr('value', col).text(col));
}
});
</script>
</div>
</div>
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment