diff --git a/ql/_dumps/structs.sql b/ql/_dumps/structs.sql
index 372e5eed1cfef37802820f88279bd9497a4e9fa1..96ca94f519fc18d7c4a6620f68396d8415f9e654 100644
--- a/ql/_dumps/structs.sql
+++ b/ql/_dumps/structs.sql
@@ -54,4 +54,14 @@ CREATE TABLE stats_test (
 	value int64
 );
 
+DROP TABLE IF EXISTS composite_keys;
+
+-- Composite keys are currently not supported in QL.
+CREATE TABLE composite_keys (
+-- code string,
+-- user_id string,
+  some_val string,
+-- primary key (code, user_id)
+);
+
 COMMIT;
diff --git a/ql/collection.go b/ql/collection.go
index 5ad91f3ad397578b12de40061452f2e45d4323fb..07b889f04502eb1df3af1a7e04d238d1b4ea580e 100644
--- a/ql/collection.go
+++ b/ql/collection.go
@@ -79,6 +79,14 @@ func whereValues(term interface{}) (where sqlgen.Where, args []interface{}) {
 		for _, kk := range k {
 			where = append(where, kk)
 		}
+	case db.Constrainer:
+		k, v := conditionValues(t.Constraint())
+		args = append(args, v...)
+		for _, kk := range k {
+			where = append(where, kk)
+		}
+	default:
+		panic(fmt.Sprintf(db.ErrUnknownConditionType.Error(), reflect.TypeOf(t)))
 	}
 
 	return where, args
@@ -245,6 +253,13 @@ func (t *table) Append(item interface{}) (interface{}, error) {
 	var id int64
 	id, _ = res.LastInsertId()
 
+	// Does the item satisfy the db.ID interface?
+	if setter, ok := item.(db.IDSetter); ok {
+		if err := setter.SetID([]interface{}{id}...); err != nil {
+			return nil, err
+		}
+	}
+
 	return id, nil
 }
 
diff --git a/ql/database_test.go b/ql/database_test.go
index 64a9b89eac6b5cb68f1466980394bf4debcf139a..6befcf76ae1365490365fef94f5428a7cfa38a36 100644
--- a/ql/database_test.go
+++ b/ql/database_test.go
@@ -34,6 +34,7 @@ import (
 
 	"menteslibres.net/gosexy/to"
 	//"reflect"
+	"errors"
 	"math/rand"
 	"strings"
 	"testing"
@@ -77,6 +78,26 @@ type testValuesStruct struct {
 	Time  time.Duration `field:"_time"`
 }
 
+type ItemWithKey struct {
+	ID      int64  `db:",omitempty"`
+	SomeVal string `db:"some_val"`
+}
+
+func (item ItemWithKey) Constraint() db.Cond {
+	cond := db.Cond{
+		"id()": item.ID,
+	}
+	return cond
+}
+
+func (item *ItemWithKey) SetID(keys ...interface{}) error {
+	if len(keys) == 1 {
+		item.ID = keys[0].(int64)
+		return nil
+	}
+	return errors.New(`Expecting exactly two keys.`)
+}
+
 var testValues testValuesStruct
 
 func init() {
@@ -1120,6 +1141,66 @@ func TestTransactionsAndRollback(t *testing.T) {
 
 }
 
+// QL: Does not support composite keys, so we're testing db.Constrainer and
+// db.IDSetter interface.
+func TestCompositeKeys(t *testing.T) {
+	var err error
+	var id interface{}
+	var sess db.Database
+	var compositeKeys db.Collection
+
+	if sess, err = db.Open(Adapter, settings); err != nil {
+		t.Fatal(err)
+	}
+
+	defer sess.Close()
+
+	if compositeKeys, err = sess.Collection("composite_keys"); err != nil {
+		t.Fatal(err)
+	}
+
+	//n := rand.Intn(100000)
+
+	item := ItemWithKey{
+		// 		"ABCDEF",
+		// 		strconv.Itoa(n),
+		0,
+		"Some value",
+	}
+
+	if id, err = compositeKeys.Append(&item); err != nil {
+		t.Fatal(err)
+	}
+
+	//	ids := id.([]interface{})
+
+	// 	if ids[0].(string) != item.Code {
+	// 		t.Fatal(`Keys must match.`)
+	// 	}
+	//
+	// 	if ids[1].(string) != item.UserID {
+	// 		t.Fatal(`Keys must match.`)
+	// 	}
+
+	// Using constraint interface.
+	res := compositeKeys.Find(ItemWithKey{ID: id.(int64)})
+
+	var item2 ItemWithKey
+
+	if item2.SomeVal == item.SomeVal {
+		t.Fatal(`Values must be different before query.`)
+	}
+
+	if err := res.One(&item2); err != nil {
+		t.Fatal(err)
+	}
+
+	if item2.SomeVal != item.SomeVal {
+		t.Fatal(`Values must be equal after query.`)
+	}
+
+}
+
 /*
 // Attempts to add many different datatypes to a single row in a collection,
 // then it tries to get the stored datatypes and check if the stored and the