diff --git a/src/Model/DB.py b/src/Model/DB.py
index 013f688e6fb5cf82cddfb932bbee8e36f3b9747e..9405ef78dea59941944b83cac46adf88a2e99d36 100644
--- a/src/Model/DB.py
+++ b/src/Model/DB.py
@@ -38,12 +38,15 @@ class SQLModel(SQL):
         fn = lambda sql: self.execute(
             sql,
             fetch_one = False,
-            commit = True
+            commit = False
         )
 
         for cls in self._sub_classes:
             requests = cls._sql_create(fn)
 
+        self.commit()
+        return True
+
     def _create(self):
         raise NotImplementedMethodeError(self, self._create)
 
@@ -51,13 +54,14 @@ class SQLModel(SQL):
         fn = lambda sql: self.execute(
             sql,
             fetch_one = False,
-            commit = True
+            commit = False
         )
 
         ok = True
         for cls in self._sub_classes:
             ok &= cls._sql_update(fn, version)
 
+        self.commit()
         return ok
 
     def _update(self):
@@ -67,13 +71,14 @@ class SQLModel(SQL):
         fn = lambda sql: self.execute(
             sql,
             fetch_one = False,
-            commit = True
+            commit = False
         )
 
         ok = True
         for obj in objs:
             ok &= obj._sql_save(fn)
 
+        self.commit()
         return ok
 
     def _save(self):
diff --git a/src/Model/Geometry/PointXYZ.py b/src/Model/Geometry/PointXYZ.py
index 9321d5bf98ef645fac5c2000b22dcec3f9106a21..bc878318fe4961e1f5556a3b4c4479dea0383379 100644
--- a/src/Model/Geometry/PointXYZ.py
+++ b/src/Model/Geometry/PointXYZ.py
@@ -21,7 +21,8 @@ class PointXYZ(Point, SQLSubModel):
     def _sql_create(cls, execute):
         execute("""
           CREATE TABLE geometry_pointXYZ(
-            id INTEGER NOT NULL PRIMARY KEY,
+            id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
+            ind INTEGER NOT NULL,
             name TEXT,
             x INTEGER NOT NULL,
             y INTEGER NOT NULL,
@@ -41,9 +42,54 @@ class PointXYZ(Point, SQLSubModel):
 
     @classmethod
     def _sql_load(cls, execute, data = None):
-        return None
+        points = []
+
+        status = data["status"]
+        profile = data["profile"]
+
+        table = execute(
+            "SELECT ind, name, x, y, z " +
+            "FROM geometry_pointXYZ " +
+            f"WHERE profile = {profile}"
+        )
+
+        # Create points list
+        for _ in table:
+            points.append(None)
+
+        # Fill points list with new point
+        for row in table:
+            ind = row[0]
+            name = row[1]
+            x = row[2]
+            y = row[3]
+            z = row[4]
+
+            new = cls(
+                name = name,
+                x = x, y = y, z = z,
+                status = status
+            )
+
+            points[ind] = new
+
+        return points
 
     def _sql_save(self, execute, data = None):
+        profile = data["profile"]
+        ind = data["ind"]
+
+        sql = (
+            "INSERT OR REPLACE INTO " +
+            "geometry_pointXYZ(ind, name, x, y, z, profile) "+
+            "VALUES (" +
+            f"{ind}, '{self._sql_format(self._name)}', " +
+            f"{self.x}, {self.y}, {self.z}, " +
+            f"{profile}" +
+            ")"
+        )
+        execute(sql)
+
         return True
 
 
diff --git a/src/Model/Geometry/Profile.py b/src/Model/Geometry/Profile.py
index f2678c68de425f632dd254f7f12afbb36f2819ab..93e2c8a8ac8122a1530fead7f2fb06b06d7443df 100644
--- a/src/Model/Geometry/Profile.py
+++ b/src/Model/Geometry/Profile.py
@@ -6,15 +6,23 @@ from Model.Geometry.Point import Point
 from Model.Except import NotImplementedMethodeError
 
 class Profile(object):
-    def __init__(self, num: int = 0,
+    _id_cnt = 0
+
+    def __init__(self, id:int = -1, num:int = 0,
                  kp:float = 0.0, name:str = "",
-                 code1: int = 0, code2: int = 0,
+                 code1:int = 0, code2:int = 0,
                  _type:str = "", reach = None,
                  status = None):
         super(Profile, self).__init__()
 
         self._status = status
 
+        if id == -1:
+            self.id = Profile._id_cnt
+            Profile._id_cnt += 1
+        else:
+            self.id = id
+
         self._num = int(num)
         self._code1 = int(code1)
         self._code2 = int(code2)
diff --git a/src/Model/Geometry/ProfileXYZ.py b/src/Model/Geometry/ProfileXYZ.py
index 2013dea31808379f40f3a82c81c3b9fad5a70166..b583fa8f23b565474795d90c6878ddcac6068d5d 100644
--- a/src/Model/Geometry/ProfileXYZ.py
+++ b/src/Model/Geometry/ProfileXYZ.py
@@ -17,6 +17,7 @@ class ProfileXYZ(Profile, SQLSubModel):
     ]
 
     def __init__(self,
+                 id: int = -1,
                  name: str = "",
                  kp: float = 0.,
                  reach = None,
@@ -37,6 +38,7 @@ class ProfileXYZ(Profile, SQLSubModel):
             Nothing.
         """
         super(ProfileXYZ, self).__init__(
+            id = id,
             num = num,
             name = name,
             kp = kp,
@@ -61,20 +63,72 @@ class ProfileXYZ(Profile, SQLSubModel):
           )
         """)
 
-        cls._create_submodel(execute)
-        return True
+        return cls._create_submodel(execute)
 
     @classmethod
     def _sql_update(cls, execute, version):
-        cls._update_submodel(execute, version)
-        return True
+        return cls._update_submodel(execute, version)
 
     @classmethod
     def _sql_load(cls, execute, data = None):
-        return None
+        profiles = []
+        status = data["status"]
+        reach = data["reach"]
+
+        table = execute(
+            "SELECT id, name, kp, num, code1, code2 " +
+            "FROM geometry_profileXYZ " +
+            f"WHERE reach = {reach}"
+        )
+
+        for row in table:
+            id = row[0]
+            name = row[1]
+            kp = row[2]
+            num = row[3]
+            code1 = row[4]
+            code2 = row[5]
+
+            new = cls(
+                id=id, num = num,
+                name = name, kp = kp,
+                code1 = code1, code2 = code2,
+                reach = data["parent"],
+                status = status
+            )
+
+            data["profile"] = id
+            new._points = PointXYZ._sql_load(execute, data)
+
+            profiles.append(new)
+
+        return profiles
 
     def _sql_save(self, execute, data = None):
-        return True
+        ok = True
+
+        sql = (
+            "INSERT OR REPLACE INTO " +
+            "geometry_profileXYZ(id, name, reach, kp, num, code1, code2) "+
+            "VALUES (" +
+            f"{self.id}, '{self._sql_format(self._name)}', " +
+            f"{self.reach.id}, {self.kp}, {self.num}, " +
+            f"{self.code1}, {self.code1}" +
+            ")"
+        )
+        execute(sql)
+
+        if data is None:
+            data = {}
+        data["profile"] = self.id
+
+        ind = 0
+        for point in self._points:
+            data["ind"] = ind
+            ok &= point._sql_save(execute, data)
+            ind += 1
+
+        return ok
 
     @classmethod
     def from_data(cls, header, data):
diff --git a/src/Model/Geometry/Reach.py b/src/Model/Geometry/Reach.py
index c5415c7693b7596fdfdcaaf97e534a299986bd58..4e69f582bdbf2ed4e1b2edef1756b6a3f7e5f319 100644
--- a/src/Model/Geometry/Reach.py
+++ b/src/Model/Geometry/Reach.py
@@ -23,6 +23,7 @@ class Reach(SQLSubModel):
     ]
 
     def __init__(self, status=None, parent=None):
+        self.id = parent.id
         self._status = status
         self._parent = parent
         self._profiles: List[Profile] = []
@@ -46,17 +47,15 @@ class Reach(SQLSubModel):
 
         new._profiles = ProfileXYZ._sql_load(
             execute,
-            data = {
-                "status": data["status"],
-                "reach": new,
-            }
+            data = data
         )
 
         return new
 
     def _sql_save(self, execute, data = None):
-        cls._save_submodel(execute, data)
-        return True
+        objs = self._profiles
+
+        return self._save_submodel(execute, objs, data)
 
     def profile(self, i):
         """Returns profile at index i
diff --git a/src/Model/River.py b/src/Model/River.py
index 452773c345eea49453094aea93f55b47f84f9a67..16095fc4ed52a7683d038788903c2a2fdd7f2295 100644
--- a/src/Model/River.py
+++ b/src/Model/River.py
@@ -127,6 +127,9 @@ class RiverReach(Edge, SQLSubModel):
     def _sql_load(cls, execute, data = None):
         reachs = []
 
+        if data is None:
+            data = {}
+
         table = execute("SELECT id, name, enable, node1, node2 FROM river_reach")
         for row in table:
             # Update id counter
@@ -141,6 +144,11 @@ class RiverReach(Edge, SQLSubModel):
 
             new = cls(id, name, node1, node2, status = data["status"])
             new.enable(enable = enable)
+
+            data["reach"] = id
+            data["parent"] = new
+            new._reach = Reach._sql_load(execute, data)
+
             reachs.append(new)
 
         return reachs
@@ -157,7 +165,8 @@ class RiverReach(Edge, SQLSubModel):
         )
         execute(sql)
 
-        return True
+        objs = [self._reach]
+        return self._save_submodel(execute, objs, data)
 
     @property
     def reach(self):
diff --git a/src/tools.py b/src/tools.py
index b54616d1e709f565b97970b6c033ed528261a12f..1c72b03127b1207e31bfe7a028d951806fbf4461 100644
--- a/src/tools.py
+++ b/src/tools.py
@@ -231,8 +231,9 @@ class SQL(object):
             value = value.replace("'", "'")
         return value
 
+    @timer
     def execute(self, cmd, fetch_one = True, commit = False):
-        print(f"[SQL] {cmd}")
+        #print(f"[SQL] {cmd}")
         res = self._cur.execute(cmd)
 
         if commit: