Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Prevent repeated imports into SQL, constraints

  • Loading branch information...
commit be4b192e5da4bc5fd79a94139e1decd5ab67a713 1 parent 642a5ca
@mlt authored
Showing with 51 additions and 29 deletions.
  1. +51 −29 src/extra/writer_sqlite.py
View
80 src/extra/writer_sqlite.py
@@ -14,42 +14,43 @@
class SQLiteWriter:
""" SQLite writer """
- track_keys = { 'Start': ('start', 'date'),
+ track_keys = { 'Start': ('start', 'date unique'),
'End': ('end', 'date'),
- 'Laps': ('laps', 'int'),
- 'MaxHeart': ('heart_max', 'int'),
- 'Heart': ('heart', 'int'),
+ 'Laps': ('laps', 'integer'),
+ 'MaxHeart': ('heart_max', 'integer'),
+ 'Heart': ('heart', 'integer'),
'MaxSpeed': ('speed_max', 'real'),
'Speed': ('speed', 'real'),
- 'Points': ('points', 'int'),
- 'Track': ('track', 'text') }
+ 'Points': ('points', 'integer'),
+ 'Track': ('track', 'text'),
+ '__foo': ('track_id', 'integer primary key autoincrement')}
lap_keys = { 'Time': ('time', 'date'),
'Speed': ('speed', 'real'),
- 'Lap': ('lap', 'int'),
+ 'Lap': ('lap', 'integer'),
'Distance': ('distance', 'real'),
'kcal': ('kcal', 'real'),
'MaxSpeed': ('speed_max', 'real'),
- 'autolap': ('autolap', 'int'),
- 'Beats': ('beats', 'int'),
- 'sec': ('sec', 'int'),
- 'MaxHeart': ('heart_max', 'int'),
- 'MinHeart': ('heart_min', 'int'),
- 'InZone': ('in_zone', 'int'),
+ 'autolap': ('autolap', 'integer'),
+ 'Beats': ('beats', 'integer'),
+ 'sec': ('sec', 'integer'),
+ 'MaxHeart': ('heart_max', 'integer'),
+ 'MinHeart': ('heart_min', 'integer'),
+ 'InZone': ('in_zone', 'integer'),
'Elevation': ('elevation', 'real') }
point_keys = { 'Distance': ('distance', 'real'),
'Speed': ('speed', 'real'),
- 'Time': ('time', 'date'),
+ 'Time': ('time', 'date primary key'),
'Heart': ('heart', 'real'),
- # 'InZone': ('in_zone', 'int'),
+ # 'InZone': ('in_zone', 'integer'),
'Latitude': ('lat', 'real'),
'Longitude': ('lon', 'real'),
'kcal': ('kcal', 'real'),
'Elevation': ('elevation', 'real')
}
- waypoint_keys = { 'Timestamp': ('time', 'date'),
+ waypoint_keys = { 'Time': ('time', 'date primary key'),
'Name': ('name', 'text'),
'Latitude': ('lat', 'real'),
'Longitude': ('lon', 'real'),
@@ -61,18 +62,25 @@ def __init__(self, dir, hook=None):
self.c = self.con.cursor()
self.hook = hook
+ self.c.execute('PRAGMA foreign_keys = ON')
self.c.execute(self._make_table_sql('tracks', self.track_keys))
- self.c.execute(self._make_table_sql('laps', self.lap_keys))
- self.c.execute(self._make_table_sql('points', self.point_keys))
+ self.c.execute(self._make_table_sql(
+ 'laps', self.lap_keys,
+ ", track_id int references tracks(track_id) ON DELETE CASCADE"))
+ self.c.execute(self._make_table_sql(
+ 'points', self.point_keys,
+ ", track_id int references tracks(track_id) ON DELETE CASCADE"))
self.c.execute(self._make_table_sql('waypoints', self.waypoint_keys))
self.tracks_with_points = deque()
@staticmethod
- def _make_table_sql(table, keys):
- sql = "CREATE TABLE IF NOT EXISTS {:s} ({:s}, track_id int)".format(
+ def _make_table_sql(table, keys, extra=None):
+ sql = "CREATE TABLE IF NOT EXISTS {:s} ({:s}{:s})".format(
table,
- ",".join( [ " ".join(x) for x in keys.itervalues() ] ))
+ ",".join( [ " ".join(x) for x in keys.itervalues() ] ),
+ extra if extra else ""
+ )
return sql
def add_track(self, track):
@@ -84,13 +92,22 @@ def add_track(self, track):
",".join(db_fields),
",".join(['?'] * len(db_fields)) )
values = [v for i, v in track.iteritems() if i in fields]
- self.c.execute(sql, values)
- self.track = self.c.lastrowid
+ self.track = None
+ self.skip = False
+ try:
+ self.c.execute(sql, values)
+ self.c.execute("SELECT track_id FROM tracks WHERE rowid=?", (self.c.lastrowid,))
+ self.track = self.c.fetchone()[0]
+ except sqlite3.IntegrityError:
+ self.skip = True
+ _log.info("Already imported. Skipping this track data.")
if track['Points'] > 0:
- self.tracks_with_points.append(self.track)
+ self.tracks_with_points.append((self.track, self.skip))
def add_lap(self, lap):
""" Append lap to a database """
+ if self.skip:
+ return
# select only those we want to keep
fields = [f for f in lap.iterkeys() if f in self.lap_keys]
db_fields = [self.lap_keys[f][0] for f in fields]
@@ -103,10 +120,12 @@ def add_lap(self, lap):
def begin_points(self, summary):
""" Points for track will follow """
self.con.commit()
- self.track = self.tracks_with_points.popleft()
+ (self.track, self.skip) = self.tracks_with_points.popleft()
def add_point(self, point):
""" Append point to a database """
+ if self.skip:
+ return
# select only those we want to keep
fields = [f for f in point.iterkeys() if f in self.point_keys]
db_fields = [self.point_keys[f][0] for f in fields]
@@ -123,14 +142,17 @@ def commit(self):
def add_waypoint(self, wp):
""" Append point to a database """
# select only those we want to keep
- fields = [f for f in wp.iterkeys() if f in self.wp_keys]
- db_fields = [self.wp_keys[f][0] for f in fields]
+ fields = [f for f in wp.iterkeys() if f in self.waypoint_keys]
+ db_fields = [self.waypoint_keys[f][0] for f in fields]
sql = """INSERT INTO waypoints ({:s}) VALUES ({:s})""".format(
",".join(db_fields),
",".join(['?'] * len(db_fields)) )
values = [v for i, v in wp.iteritems() if i in fields]
- self.c.execute(sql, values)
- self.con.commit()
+ try:
+ self.c.execute(sql, values)
+ self.con.commit()
+ except sqlite3.IntegrityError:
+ pass
if __name__ == '__main__':
logging.basicConfig(level=logging.WARNING)
Please sign in to comment.
Something went wrong with that request. Please try again.