diff --git a/src/Model/InitialConditions/InitialConditions.py b/src/Model/InitialConditions/InitialConditions.py
index 57d582c2b3399a1001e5c257b2eba33d365e0898..9b2264879009d420618c3cb568b8fe6cf31ada63 100644
--- a/src/Model/InitialConditions/InitialConditions.py
+++ b/src/Model/InitialConditions/InitialConditions.py
@@ -4,33 +4,121 @@ from copy import copy, deepcopy
 from tools import trace, timer
 from functools import reduce
 
-class Data(object):
-    def __init__(self, reach = None, status = None):
+from Model.DB import SQLSubModel
+
+class Data(SQLSubModel):
+    def __init__(self, name:str = "",
+                 comment:str = "", reach = None,
+                 kp:float = 0.0, discharge:float = 0.0,
+                 height:float = 0.0,
+                 status = None):
         super(Data, self).__init__()
 
         self._status = status
 
         self._reach = reach
 
-        self._name = ""
-        self._comment = ""
+        self._name = name
+        self._comment = comment
 
-        self._kp = 0.0
-        self._discharge = 0.0
+        self._kp = kp
+        self._discharge = discharge
         self._speed = 0.0
         self._elevation = 0.0
-        self._height = 0.0
+        self._height = height
 
-    def copy(self):
-        new = Data(self._reach, self._status)
+        if self._kp != 0.0:
+            self._update_from_kp()
+        if self._height != 0.0:
+            self._update_from_height()
+        if self._discharge != 0.0:
+            self._update_from_discharge()
+
+    @classmethod
+    def _sql_create(cls, execute):
+        execute("""
+          CREATE TABLE initial_conditions(
+            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+            ind INTEGER NOT NULL,
+            name TEXT NOT NULL,
+            comment TEXT NOT NULL,
+            reach INTEGER,
+            kp REAL NOT NULL,
+            discharge REAL NOT NULL,
+            height REAL NOT NULL,
+            FOREIGN KEY(reach) REFERENCES river_reach(id)
+          )
+        """)
+
+        return cls._create_submodel(execute)
+
+    @classmethod
+    def _sql_update(cls, execute, version):
+        return cls._update_submodel(execute, version)
+
+    @classmethod
+    def _sql_load(cls, execute, data = None):
+        id = data["reach"].id
+        table = execute(
+            "SELECT ind, name, comment, kp, discharge, height " +
+            "FROM initial_conditions " +
+            f"WHERE reach = {id}"
+        )
+
+        new = []
+
+        for _ in table:
+            new.append(None)
+
+        for row in table:
+            ind = row[0]
+            name = row[1]
+            comment = row[2]
+            kp = row[3]
+            discharge = row[4]
+            height = row[5]
+
+            d = cls(
+                reach = data["reach"],
+                status = data["status"],
+                name = name,
+                comment = comment,
+                kp = kp,
+                discharge = discharge,
+                height = height,
+            )
 
-        new._name = self._name
-        new._comment = self._comment
-        new._kp = self._kp
-        new._discharge = self._discharge
-        new._speed = self._speed
-        new._elevation = self._elevation
-        new._height = self._height
+            new[ind] = d
+
+        return new
+
+    def _sql_save(self, execute, data = None):
+        ind = data["ind"]
+
+        execute(
+            "INSERT INTO " +
+            "initial_conditions(ind, name, comment, kp, discharge, height, reach) " +
+            "VALUES (" +
+            f"{ind}, '{self._sql_format(self.name)}', " +
+            f"'{self._sql_format(self._comment)}', " +
+            f"{self._kp}, {self._discharge}, {self._height}, " +
+            f"{self._reach.id}" +
+            ")"
+        )
+
+        return True
+
+
+    def copy(self):
+        new = Data(
+            name = self.name,
+            comment = self._comment,
+            kp = self._kp,
+            discharge = self._discharge,
+            height = self._height,
+            reach = self._reach,
+            status = self._status,
+        )
 
         return new
 
@@ -92,8 +180,8 @@ class Data(object):
             self._kp = float(value)
             self._update_from_kp()
         elif key == "speed":
-            self._speed = float(value)
             # Not supposed to be modified
+            self._speed = float(value)
         elif key == "discharge":
             self._discharge = float(value)
             self._update_from_discharge()
@@ -106,7 +194,12 @@ class Data(object):
 
         self._status.modified()
 
-class InitialConditions(object):
+
+class InitialConditions(SQLSubModel):
+    _sub_classes = [
+        Data
+    ]
+
     def __init__(self, reach = None, status = None):
         super(InitialConditions, self).__init__()
 
@@ -115,6 +208,42 @@ class InitialConditions(object):
         self._reach = reach
         self._data = []
 
+    @classmethod
+    def _sql_create(cls, execute):
+        return cls._create_submodel(execute)
+
+    @classmethod
+    def _sql_update(cls, execute, version):
+        return cls._update_submodel(execute, version)
+
+    @classmethod
+    def _sql_load(cls, execute, data = None):
+        new = cls(
+            reach = data["reach"],
+            status = data["status"]
+        )
+
+        new._data = Data._sql_load(
+            execute,
+            data = data
+        )
+
+        if new._data is None:
+            return None
+
+        return new
+
+    def _sql_save(self, execute, data = None):
+        ok = True
+
+        ind = 0
+        for d in self._data:
+            data["ind"] = ind
+            ok &= d._sql_save(execute, data)
+            ind += 1
+
+        return ok
+
     def __len__(self):
         return len(self._data)
 
diff --git a/src/Model/InitialConditions/InitialConditionsDict.py b/src/Model/InitialConditions/InitialConditionsDict.py
index 71d707d07af230f0f5fb419451af4fbdf5a3f48b..5e8d5fbac9764527a8843312683c932ecbca3ef2 100644
--- a/src/Model/InitialConditions/InitialConditionsDict.py
+++ b/src/Model/InitialConditions/InitialConditionsDict.py
@@ -3,9 +3,14 @@
 from copy import copy
 from tools import trace, timer
 
+from Model.DB import SQLSubModel
 from Model.InitialConditions.InitialConditions import InitialConditions
 
-class InitialConditionsDict(object):
+class InitialConditionsDict(SQLSubModel):
+    _sub_classes = [
+        InitialConditions,
+    ]
+
     def __init__(self, status = None):
         super(InitialConditionsDict, self).__init__()
 
@@ -13,6 +18,44 @@ class InitialConditionsDict(object):
 
         self._reach = {}
 
+    @classmethod
+    def _sql_create(cls, execute):
+        return cls._create_submodel(execute)
+
+    @classmethod
+    def _sql_update(cls, execute, version):
+        return cls._update_submodel(execute, version)
+
+    @classmethod
+    def _sql_load(cls, execute, data = None):
+        new = cls(status = data["status"])
+
+        for reach in data["edges"]:
+            data["reach"] = reach
+
+            ic = InitialConditions._sql_load(
+                execute,
+                data = data
+            )
+
+            if ic is not None:
+                new._reach[reach] = ic
+
+        return new
+
+    def _sql_save(self, execute, data = None):
+        ok = True
+        if data is None:
+            data = {}
+
+        execute("DELETE FROM initial_conditions")
+
+        for reach in self._reach:
+            data["reach"] = reach
+            ok &= self._reach[reach]._sql_save(execute, data)
+
+        return ok
+
     def __len__(self):
         return len(self._reach)
 
diff --git a/src/Model/River.py b/src/Model/River.py
index 8a4f6fc69d184e6284f4661bc8d1053a0ba0ae2e..15f3e6e4e2c2c3aed9c8f19f04c1ab422d23eac4 100644
--- a/src/Model/River.py
+++ b/src/Model/River.py
@@ -182,7 +182,7 @@ class River(Graph, SQLSubModel):
         RiverReach,
         BoundaryConditionList,
         LateralContributionList,
-        # InitialConditionsDict,
+        InitialConditionsDict,
         StricklersList,
         SolverParametersList,
     ]
@@ -237,6 +237,13 @@ class River(Graph, SQLSubModel):
             execute,
             data
         )
+
+        # Initial conditions
+        new._initial_conditions = InitialConditionsDict._sql_load(
+            execute,
+            data
+        )
+
         # Stricklers
         new._stricklers = StricklersList._sql_load(
             execute,
@@ -256,8 +263,10 @@ class River(Graph, SQLSubModel):
     def _sql_save(self, execute, data = None):
         objs = (self._nodes + self._edges)
         objs.append(self._boundary_condition)
+        objs.append(self._initial_conditions)
         objs.append(self._lateral_contribution)
         objs.append(self._stricklers)
+
         for solver in self._parameters:
             objs.append(self._parameters[solver])