diff --git a/toardb/auth_user/models.py b/toardb/auth_user/models.py
index f595e0c7e9c7ea32847f49a00fbe3f0730d84435..5f644ed4c381c523e00a4352bd14c9e94dd2ece2 100644
--- a/toardb/auth_user/models.py
+++ b/toardb/auth_user/models.py
@@ -3,10 +3,8 @@ from sqlalchemy import ARRAY, BigInteger, Boolean, CheckConstraint, Column, Date
 from sqlalchemy.orm import relationship
 from geoalchemy2.types import Geometry
 from sqlalchemy.dialects.postgresql import JSONB
-from sqlalchemy.ext.declarative import declarative_base
+from toardb.base import Base
 
-Base = declarative_base()
-metadata = Base.metadata
 
 class AuthUser(Base):
     __tablename__ = 'auth_user'
diff --git a/toardb/base.py b/toardb/base.py
new file mode 100644
index 0000000000000000000000000000000000000000..531e94bff4f9baa3766cdbf1cbd87bece716803a
--- /dev/null
+++ b/toardb/base.py
@@ -0,0 +1,6 @@
+# coding: utf-8
+from sqlalchemy.ext.declarative import declarative_base
+
+Base = declarative_base()
+metadata = Base.metadata
+
diff --git a/toardb/contacts/models.py b/toardb/contacts/models.py
index a39c643d21663d66d46568fba0e3ebaebbc902b4..f863c1a218f89603eeec066d5b186a58b16ce35c 100644
--- a/toardb/contacts/models.py
+++ b/toardb/contacts/models.py
@@ -1,18 +1,6 @@
-#taken from: https://stackoverflow.com/questions/29954815/merge-multiple-declarative-bases-in-sqlalchemy
-from sqlalchemy import MetaData
-from sqlalchemy.ext.declarative import declarative_base
-from .models_person import (
-        Person,
-        Base as PersonBase)
-from .models_organisation import (
-        Organisation,
-        Base as OrganisationBase)
+# coding: utf-8
+from toardb.base import Base
 
-Base = declarative_base()
-metadata = MetaData()
+from .models_person import Person
+from .models_organisation import Organisation
 
-for declarative_base in [PersonBase, OrganisationBase]:
-    for (table_name, table) in declarative_base.metadata.tables.items():
-        metadata._add_table(table_name, table.schema, table)
-
-Base.metadata = metadata
diff --git a/toardb/contacts/models_organisation.py b/toardb/contacts/models_organisation.py
index c7f23c3d01c11e7842d8db51dfb71b37bfac6ff6..dcf8f9c7502b77a28149d72880b91481e889f18d 100644
--- a/toardb/contacts/models_organisation.py
+++ b/toardb/contacts/models_organisation.py
@@ -4,10 +4,7 @@ class Organisation (Base)
 =========================
 """
 from sqlalchemy import CheckConstraint, Column, Integer, String, text
-from sqlalchemy.ext.declarative import declarative_base
-
-Base = declarative_base()
-metadata = Base.metadata
+from toardb.base import Base
 
 
 class Organisation(Base):
diff --git a/toardb/contacts/models_person.py b/toardb/contacts/models_person.py
index d8fe29aadff6a27faedba2d34192249c2f0376f6..aa31af4c9c1658cc968c552eb3352ee262c2ca7e 100644
--- a/toardb/contacts/models_person.py
+++ b/toardb/contacts/models_person.py
@@ -4,10 +4,7 @@ class Person (Base)
 ===================
 """
 from sqlalchemy import Boolean, Column, Integer, String, text
-from sqlalchemy.ext.declarative import declarative_base
-
-Base = declarative_base()
-metadata = Base.metadata
+from toardb.base import Base
 
 class Person(Base):
     """ Table "public.persons"
diff --git a/toardb/data/models.py b/toardb/data/models.py
index a8d9b14fbd965eefbf9446a8dcbad1b90bc273c0..3d08600a1efbc86e14b0719a0ec18eee42f799b7 100644
--- a/toardb/data/models.py
+++ b/toardb/data/models.py
@@ -3,12 +3,9 @@ from sqlalchemy import PrimaryKeyConstraint, Column, DateTime, Float, ForeignKey
 from sqlalchemy.orm import relationship
 from sqlalchemy.sql.sqltypes import NullType
 from sqlalchemy.dialects.postgresql import JSONB
-from sqlalchemy.ext.declarative import declarative_base
 
 from toardb.timeseries.models import Timeseries
-
-Base = declarative_base()
-metadata = Base.metadata
+from toardb.base import Base
 
 
 class Data(Base):
diff --git a/toardb/stationmeta/models.py b/toardb/stationmeta/models.py
index 04c9641729b6a4105c5f06fdcf757234f7acf2d5..debb835d0b35857740194fd667e28abe493a3055 100644
--- a/toardb/stationmeta/models.py
+++ b/toardb/stationmeta/models.py
@@ -1,31 +1,9 @@
-#taken from: https://stackoverflow.com/questions/29954815/merge-multiple-declarative-bases-in-sqlalchemy
-from sqlalchemy import MetaData
 from sqlalchemy.ext.declarative import declarative_base
-from .models_core import (
-        StationmetaCore,
-        Base as StationmetaCoreBase)
-from .models_global import (
-        StationmetaGlobal,
-        Base as StationmetaGlobalBase)
-from .models_global_services import (
-        StationmetaGlobalService,
-        Base as StationmetaGlobalServiceBase)
-from .models_role import (
-        StationmetaRole,
-        Base as StationmetaRoleBase)
-from .models_annotation import (
-        StationmetaAnnotation,
-        Base as StationmetaAnnotationBase)
-from .models_aux import (
-        StationmetaAuxDoc, StationmetaAuxImage, StationmetaAuxUrl,
-        Base as StationmetaAuxBase)
+from .models_core import StationmetaCore
+from .models_global import StationmetaGlobal
+from .models_global_services import StationmetaGlobalService
+from .models_role import StationmetaRole, stationmeta_core_stationmeta_roles_table
+from .models_annotation import StationmetaAnnotation, stationmeta_core_stationmeta_annotations_table
+from .models_aux import StationmetaAuxDoc, StationmetaAuxImage, StationmetaAuxUrl
 
-Base = declarative_base()
-metadata = MetaData()
-
-for declarative_base in [StationmetaCoreBase, StationmetaGlobalBase, StationmetaGlobalServiceBase,
-                         StationmetaRoleBase, StationmetaAnnotationBase, StationmetaAuxBase]:
-    for (table_name, table) in declarative_base.metadata.tables.items():
-        metadata._add_table(table_name, table.schema, table)
-
-Base.metadata = metadata
+from toardb.base import Base
diff --git a/toardb/stationmeta/models_annotation.py b/toardb/stationmeta/models_annotation.py
index 49e8d15801632324faa03de7a21e7a0dff1e8d16..fd31faf860b1d78bc16fb4bc327d1d440b88764b 100644
--- a/toardb/stationmeta/models_annotation.py
+++ b/toardb/stationmeta/models_annotation.py
@@ -4,14 +4,18 @@ class StationmetaAnnotation (Base)
 ==================================
 """
 from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, text, String, \
-                       Text, Boolean, CheckConstraint
-#from sqlalchemy.orm import relationship
-from sqlalchemy.ext.declarative import declarative_base
+                       Text, Boolean, CheckConstraint, Table
+from sqlalchemy.orm import relationship
 from toardb.auth_user.models import AuthUser
-from .models_core import StationmetaCore 
+from toardb.base import Base
+
+
+# many-to-many relationships
+stationmeta_core_stationmeta_annotations_table = Table('stationmeta_core_stationmeta_annotations', Base.metadata,
+    Column('station_id', Integer, ForeignKey('stationmeta_core.id')),
+    Column('annotation_id', Integer, ForeignKey('stationmeta_annotations.id'))
+)
 
-Base = declarative_base()
-metadata = Base.metadata
 
 class StationmetaAnnotation(Base):
     """ Table "public.stationmeta_annotations"
@@ -31,16 +35,12 @@ class StationmetaAnnotation(Base):
     +----------------+--------------------------+-----------+----------+----------------------------------------------------+
     | contributor_id | integer                  |           | not null |                                                    |
     +----------------+--------------------------+-----------+----------+----------------------------------------------------+
-    | station_id     | integer                  |           | not null |                                                    |
-    +----------------+--------------------------+-----------+----------+----------------------------------------------------+
     Indexes:
      "stationmeta_annotations_pkey" PRIMARY KEY, btree (id)
      "stationmeta_annotations_contributor_id_a5009820" btree (contributor_id)
-     "stationmeta_annotations_station_id_9d3fe3d0" btree (station_id)
     Check constraints:
      "stationmeta_annotations_kind_check" CHECK (kind >= 0)
     Foreign-key constraints:
-     "stationmeta_annotati_station_id_9d3fe3d0_fk_stationme" FOREIGN KEY (station_id) REFERENCES stationmeta_core(id) DEFERRABLE INITIALLY DEFERRED
      "stationmeta_annotations_contributor_id_a5009820_fk_auth_user_id" FOREIGN KEY (contributor_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
     """
     __tablename__ = 'stationmeta_annotations'
@@ -57,7 +57,10 @@ class StationmetaAnnotation(Base):
 # use the explicit class name here,
 # see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
     contributor_id = Column(ForeignKey(AuthUser.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
-    station_id = Column(ForeignKey(StationmetaCore.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
 # how to reactivate the following two lines?!
 #   contributor = relationship('AuthUser')
-#   station = relationship('StationmetaCore')
+
+    stationmeta_core = relationship("StationmetaCore",
+        secondary=stationmeta_core_stationmeta_annotations_table,
+        backref="annotations")
+
diff --git a/toardb/stationmeta/models_aux.py b/toardb/stationmeta/models_aux.py
index c42686392bb860d762857a002a8bc0e7870943e9..3f754c7e413bcb83515b07c6da4af46540a349c6 100644
--- a/toardb/stationmeta/models_aux.py
+++ b/toardb/stationmeta/models_aux.py
@@ -14,11 +14,9 @@ class StationMetaAuxImage (Base)
 """
 from sqlalchemy import CheckConstraint, Column, DateTime, ForeignKey, Integer, String, Text, text
 #from sqlalchemy.orm import relationship
-from sqlalchemy.ext.declarative import declarative_base
 from .models_core import StationmetaCore
+from toardb.base import Base
 
-Base = declarative_base()
-metadata = Base.metadata
 
 class StationmetaAuxDoc(Base):
     """ Table "public.stationmeta_aux_doc"
diff --git a/toardb/stationmeta/models_core.py b/toardb/stationmeta/models_core.py
index 36b2d39ac162145cf13823697ebad32f45ece099..e4498c74d968ccd7035cdea8b7427b02b0cb25d3 100644
--- a/toardb/stationmeta/models_core.py
+++ b/toardb/stationmeta/models_core.py
@@ -8,12 +8,9 @@ from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, text, Strin
 from geoalchemy2.types import Geometry
 from sqlalchemy.orm import relationship
 from sqlalchemy.dialects.postgresql import JSONB, ARRAY
-from sqlalchemy.ext.declarative import declarative_base
 from shapely import wkt
 from toardb.auth_user.models import AuthUser
-
-Base = declarative_base()
-metadata = Base.metadata
+from toardb.base import Base
 
 
 class StationmetaCore(Base):
diff --git a/toardb/stationmeta/models_global.py b/toardb/stationmeta/models_global.py
index 9f3040c97db63811a7c7098c4d6e469aab141b0d..a4960507b6eb70f0cab0700edbb2ecd9d9d017ba 100644
--- a/toardb/stationmeta/models_global.py
+++ b/toardb/stationmeta/models_global.py
@@ -8,12 +8,8 @@ from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, text, Strin
 from geoalchemy2.types import Geometry
 from sqlalchemy.orm import relationship
 from sqlalchemy.dialects.postgresql import JSONB, ARRAY
-from sqlalchemy.ext.declarative import declarative_base
-from shapely import wkt
 from .models_core import StationmetaCore
-
-Base = declarative_base()
-metadata = Base.metadata
+from toardb.base import Base
 
 
 class StationmetaGlobal(Base):
diff --git a/toardb/stationmeta/models_global_services.py b/toardb/stationmeta/models_global_services.py
index 7b63f479103555f5693d322e2c56134e0f41e3ab..a0c99b7c661c4c3ec5a82d9e9a578da684e1ffc1 100644
--- a/toardb/stationmeta/models_global_services.py
+++ b/toardb/stationmeta/models_global_services.py
@@ -4,10 +4,7 @@ class StationmetaGlobalService (Base)
 =====================================
 """
 from sqlalchemy import CheckConstraint, Column, Integer, String, text
-from sqlalchemy.ext.declarative import declarative_base
-
-Base = declarative_base()
-metadata = Base.metadata
+from toardb.base import Base    
 
 class StationmetaGlobalService(Base):
     """ Table "public.stationmeta_global_services"
diff --git a/toardb/stationmeta/models_role.py b/toardb/stationmeta/models_role.py
index 29e6d49393ea42ba0d13ba32e1628d216df1ad37..4d6b6602ef54d7324ee6c4a4fb166b4426eabe11 100644
--- a/toardb/stationmeta/models_role.py
+++ b/toardb/stationmeta/models_role.py
@@ -4,14 +4,18 @@ class StationmetaRole (Base)
 ============================
 """
 from sqlalchemy import Column, ForeignKey, Integer, text, \
-                       CheckConstraint, UniqueConstraint
-#from sqlalchemy.orm import relationship
-from sqlalchemy.ext.declarative import declarative_base
+                       CheckConstraint, UniqueConstraint, Table
+from sqlalchemy.orm import relationship
 from toardb.contacts.models import Person
-from .models_core import StationmetaCore
+from toardb.base import Base
+
+
+# many-to-many relationships
+stationmeta_core_stationmeta_roles_table = Table('stationmeta_core_timeseries_roles', Base.metadata,
+    Column('station_id', Integer, ForeignKey('stationmeta_core.id')),
+    Column('role_id', Integer, ForeignKey('stationmeta_roles.id'))
+)
 
-Base = declarative_base()
-metadata = Base.metadata
 
 class StationmetaRole(Base):
     """ Table "public.stationmeta_roles"
@@ -27,26 +31,20 @@ class StationmetaRole(Base):
     +------------+---------+-----------+----------+-------------------------------------------+
     | person_id  | integer |           | not null |                                           |
     +------------+---------+-----------+----------+-------------------------------------------+
-    | station_id | integer |           | not null |                                           |
-    +------------+---------+-----------+----------+-------------------------------------------+
     Indexes:
      "stationmeta_roles_pkey" PRIMARY KEY, btree (id)
-     "stationmeta_roles_station_id_role_person_id_29a832af_uniq" UNIQUE CONSTRAINT, btree (station_id, role, person_id)
      "stationmeta_roles_person_id_3bd9c160" btree (person_id)
-     "stationmeta_roles_station_id_f31f80fc" btree (station_id)
     Check constraints:
      "stationmeta_roles_role_check" CHECK (role >= 0)
      "stationmeta_roles_status_check" CHECK (status >= 0)
     Foreign-key constraints:
      "stationmeta_roles_person_id_3bd9c160_fk_persons_id" FOREIGN KEY (person_id) REFERENCES persons(id) DEFERRABLE INITIALLY DEFERRED
-     "stationmeta_roles_station_id_f31f80fc_fk_stationmeta_core_id" FOREIGN KEY (station_id) REFERENCES stationmeta_core(id) DEFERRABLE INITIALLY DEFERRED
     """
 
     __tablename__ = 'stationmeta_roles'
     __table_args__ = (
         CheckConstraint('role >= 0'),
-        CheckConstraint('status >= 0'),
-        UniqueConstraint('station_id', 'role', 'person_id')
+        CheckConstraint('status >= 0')
     )
 
     id = Column(Integer, primary_key=True, server_default=text("nextval('stationmeta_roles_id_seq'::regclass)"))
@@ -56,8 +54,10 @@ class StationmetaRole(Base):
 # use the explicit class name here,
 # see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
     person_id = Column(ForeignKey(Person.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
-    station_id = Column(ForeignKey(StationmetaCore.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
 # how to reactivate the following two lines?!
 #   person = relationship('Person')
-#   station = relationship('Station')
+
+    stationmeta_core = relationship("StationmetaCore",
+                           secondary=stationmeta_core_stationmeta_roles_table,
+                           backref="roles")
 
diff --git a/toardb/stationmeta/test_base.py b/toardb/stationmeta/test_base.py
index bd411c787b28c7cf12c811f968238262ceb5a698..55575696b5b2021a36e1776537329e6dfb80ad59 100644
--- a/toardb/stationmeta/test_base.py
+++ b/toardb/stationmeta/test_base.py
@@ -9,8 +9,6 @@ from sqlalchemy_utils import database_exists, create_database, drop_database
 
 from toardb.utils.database import DATABASE_URL
 from .models import Base
-from toardb.auth_user.models import Base as AuthUserBase
-from toardb.contacts.models import Base as ContactBase
 from toardb.toardb import app
 from toardb.stationmeta.stationmeta import get_db
 
@@ -70,8 +68,6 @@ def create_test_database():
     fake_conn.commit()
     fake_cur.execute("CREATE SEQUENCE public.organisations_id_seq AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1")
     fake_conn.commit()
-    AuthUserBase.metadata.create_all(_db_conn)  # Create the tables.
-    ContactBase.metadata.create_all(_db_conn)  # Create the tables.
     Base.metadata.create_all(_db_conn)  # Create the tables.
     #try with the basics
     app.dependency_overrides[get_db] = get_test_db  # Mock the Database Dependency
@@ -87,7 +83,7 @@ def test_db_session():
 
     yield session
     # Drop all data after each test
-    for tbl in reversed(ContactBase.metadata.sorted_tables + AuthUserBase.metadata.sorted_tables + Base.metadata.sorted_tables):
+    for tbl in reversed(Base.metadata.sorted_tables):
         _db_conn.execute(tbl.delete())
     # put back the connection to the connection pool
     session.close()
diff --git a/toardb/timeseries/crud.py b/toardb/timeseries/crud.py
index 0988f9ab33c19f579f43c34a846c11a0fab25aae..d0f4364b23b4c73620e1b089bc10350185857065 100644
--- a/toardb/timeseries/crud.py
+++ b/toardb/timeseries/crud.py
@@ -55,6 +55,13 @@ def get_unique_timeseries_role(db: Session, role: int, person_id: int, status: i
                                       .first()
     return db_object
 
+# is this internal, or should this also go to public REST api?
+def get_unique_timeseries_programme(db: Session, name: str, homepage: str):
+    db_object = db.query(models.TimeseriesProgramme).filter(models.TimeseriesProgramme.name == name) \
+                                      .filter(models.TimeseriesProgramme.homepage == homepage) \
+                                      .first()
+    return db_object
+
 
 def __get_status_enum(db: Session):
     return db.query(RS_enum).all()
@@ -69,13 +76,15 @@ def create_timeseries(db: Session, timeseries: TimeseriesCreate):
     enum_RC = __get_role_enum(db)
     timeseries_dict = timeseries.dict()
     roles_data = timeseries_dict.pop('roles', None)
+    annotations_data = timeseries_dict.pop('annotations', None)
+    programmes_data = timeseries_dict.pop('programmes', None)
     db_timeseries = models.Timeseries(**timeseries_dict)
     db.add(db_timeseries)
     result = db.commit()
     db.refresh(db_timeseries)
     # get timeseries_id
     timeseries_id = db_timeseries.id
-    # store roles and update associaton table
+    # store roles and update association table
     if roles_data:
         for r in roles_data:
             db_role = models.TimeseriesRole(**r)
@@ -90,6 +99,33 @@ def create_timeseries(db: Session, timeseries: TimeseriesCreate):
                 role_id = db_role.id
             db.execute(insert(timeseries_timeseries_roles_table).values(timeseries_id=timeseries_id, role_id=role_id))
             db.commit()
+    # store annotations and update association table
+    if annotations_data:
+        for a in annotations_data:
+            db_annotation = models.TimeseriesAnnotation(**a)
+            db.add(db_annotation)
+            db.commit()
+            db.refresh(db_annotation)
+            annotation_id = db_annotation.id
+            db.execute(insert(timeseries_timeseries_annotations_table).values(timeseries_id=timeseries_id, annotation_id=annotation_id))
+            db.commit()
+    # store programmes and update association table
+    if programmes_data:
+        for r in programmes_data:
+            db_programme = models.TimeseriesProgramme(**r)
+            # check whether programme is already present in database
+            db_object = get_unique_timeseries_programme(db, db_programme.name, db_programme.homepage)
+            if db_object:
+                programme_id = db_object.id
+            else:
+                db.add(db_programme)
+                db.commit()
+                db.refresh(db_programme)
+                programme_id = db_programme.id
+            db.execute(insert(timeseries_timeseries_programmes_table).values(timeseries_id=timeseries_id, programme_id=programme_id))
+            db.commit()
+    # there is a mismatch with additional_metadata
+    # there is a mismatch with additional_metadata
     # there is a mismatch with additional_metadata
     # in upload command, we have now: "additional_metadata": "{}"
     # but return from this method gives (=database): "additional_metadata": {}
diff --git a/toardb/timeseries/models.py b/toardb/timeseries/models.py
index 21a4dc4dc3fc33d5d22b7133ad9723f06f0c1349..4314698276028f5c6703ebfb1b9fed037f5d1cbe 100644
--- a/toardb/timeseries/models.py
+++ b/toardb/timeseries/models.py
@@ -1,43 +1,21 @@
-#taken from: https://stackoverflow.com/questions/29954815/merge-multiple-declarative-bases-in-sqlalchemy
-from sqlalchemy import MetaData
-from sqlalchemy.ext.declarative import declarative_base
-from .models_core import (
-        Timeseries,
-        TimeseriesRole,
-        timeseries_timeseries_roles_table,
-        Base as TimeseriesBase)
-from .models_annotation import (
-        TimeseriesAnnotation,
-        Base as TimeseriesAnnotationBase)
-from .models_programme import (
-        TimeseriesProgramme,
-        Base as TimeseriesProgrammBase)
-
-Base = declarative_base()
-metadata = MetaData()
+from .models_core import Timeseries
+from .models_role import TimeseriesRole, timeseries_timeseries_roles_table
+from .models_annotation import TimeseriesAnnotation, timeseries_timeseries_annotations_table
+from .models_programme import TimeseriesProgramme, timeseries_timeseries_programmes_table
+from toardb.base import Base
 
 from sqlalchemy import Table, String, Column, ForeignKey, Integer
-from sqlalchemy.ext.declarative import declarative_base
-
-Base = declarative_base()
-metadata = Base.metadata
-
-for declarative_base in [TimeseriesBase, TimeseriesAnnotationBase, TimeseriesProgrammBase]:
-    for (table_name, table) in declarative_base.metadata.tables.items():
-        metadata._add_table(table_name, table.schema, table)
-
-Base.metadata = metadata
 
 # controlled vocabulary
 RS_enum = Table("rs_vocabulary",
-                metadata,
+                Base.metadata,
                 Column("enum_val", Integer, primary_key=True),
                 Column("enum_str", String),
                 Column("enum_display_str", String)
           )
 
 RC_enum = Table("rc_vocabulary",
-                metadata,
+                Base.metadata,
                 Column("enum_val", Integer, primary_key=True),
                 Column("enum_str", String),
                 Column("enum_display_str", String)
diff --git a/toardb/timeseries/models_annotation.py b/toardb/timeseries/models_annotation.py
index dfc781433e9b4062527ab1c2a1332c4e579878fe..43b0c3ef5c72985afa130af42e378fded4276383 100644
--- a/toardb/timeseries/models_annotation.py
+++ b/toardb/timeseries/models_annotation.py
@@ -4,14 +4,17 @@ class TimeseriesAnnotation(Base)
 ================================
 """
 from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, text, String, \
-                       Text, Boolean, CheckConstraint
-#from sqlalchemy.orm import relationship
-from sqlalchemy.ext.declarative import declarative_base
+                       Text, Boolean, CheckConstraint, Table
+from sqlalchemy.orm import relationship
 from toardb.auth_user.models import AuthUser
-from .models_core import Timeseries
+from toardb.base import Base
+
+# many-to-many relationships
+timeseries_timeseries_annotations_table = Table('timeseries_timeseries_annotations', Base.metadata,
+    Column('timeseries_id', Integer, ForeignKey('timeseries.id')),
+    Column('annotation_id', Integer, ForeignKey('timeseries_annotations.id'))
+)
 
-Base = declarative_base()
-metadata = Base.metadata
 
 class TimeseriesAnnotation(Base):
     """ Table "public.timeseries_annotations"
@@ -31,17 +34,13 @@ class TimeseriesAnnotation(Base):
     +----------------+--------------------------+-----------+----------+----------------------------------------------------+
     | contributor_id | integer                  |           | not null |                                                    |
     +----------------+--------------------------+-----------+----------+----------------------------------------------------+
-    | timeseries_id  | integer                  |           | not null |                                                    |
-    +----------------+--------------------------+-----------+----------+----------------------------------------------------+
     Indexes:
         "timeseries_annotations_pkey" PRIMARY KEY, btree (id)
         "timeseries_annotations_contributor_id_7a1758f6" btree (contributor_id)
-        "timeseries_annotations_timeseries_id_02014000" btree (timeseries_id)
     Check constraints:
         "timeseries_annotations_kind_check" CHECK (kind >= 0)
     Foreign-key constraints:
         "timeseries_annotations_contributor_id_7a1758f6_fk_auth_user_id" FOREIGN KEY (contributor_id) REFERENCES auth_user(id) DEFERRABLE INITIALLY DEFERRED
-        "timeseries_annotations_timeseries_id_02014000_fk_timeseries_id" FOREIGN KEY (timeseries_id) REFERENCES timeseries(id) DEFERRABLE INITIALLY DEFERRED
     """
     __tablename__ = 'timeseries_annotations'
     __table_args__ = (
@@ -57,7 +56,11 @@ class TimeseriesAnnotation(Base):
 # use the explicit class name here,
 # see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
     contributor_id = Column(ForeignKey(AuthUser.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
-    timeseries_id = Column(ForeignKey(Timeseries.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
 # how to reactivate the following two lines?!
 #   contributor = relationship('AuthUser')
 #   timeseries = relationship('Timeseries')
+
+    timeseries = relationship("Timeseries",
+        secondary=timeseries_timeseries_annotations_table,
+        backref="annotations")
+
diff --git a/toardb/timeseries/models_core.py b/toardb/timeseries/models_core.py
index 04360b5839f540e1901dd3a30c8a5edad0d80524..81df7e15fe71d574410cfae85ad235550dd6b35a 100644
--- a/toardb/timeseries/models_core.py
+++ b/toardb/timeseries/models_core.py
@@ -4,70 +4,11 @@ class Timeseries (Base)
 =======================
 """
 from sqlalchemy import Column, DateTime, Float, ForeignKey, Integer, text, String, \
-                       Text, CheckConstraint, UniqueConstraint, PrimaryKeyConstraint, \
-                       Table
-from sqlalchemy.orm import relationship
+                       Text, CheckConstraint, UniqueConstraint, PrimaryKeyConstraint
 from sqlalchemy.dialects.postgresql import JSONB
-from sqlalchemy.ext.declarative import declarative_base
 from toardb.stationmeta.models import StationmetaCore
 from toardb.variables.models import Variable
-from toardb.contacts.models import Person
-
-Base = declarative_base()
-metadata = Base.metadata
-
-# many-to-many relationships
-timeseries_timeseries_roles_table = Table('timeseries_timeseries_roles', Base.metadata,
-    Column('timeseries_id', Integer, ForeignKey('timeseries.id')),
-    Column('role_id', Integer, ForeignKey('timeseries_roles.id'))
-)
-
-
-class TimeseriesRole(Base):
-    """ Table "public.timeseries_roles"
-
-    +---------------+---------+-----------+----------+----------------------------------------------+
-    |    Column     |  Type   | Collation | Nullable |                   Default                    |
-    +===============+=========+===========+==========+==============================================+
-    | id            | integer |           | not null | nextval('timeseries_roles_id_seq'::regclass) |
-    +---------------+---------+-----------+----------+----------------------------------------------+
-    | role          | integer |           | not null |                                              |
-    +---------------+---------+-----------+----------+----------------------------------------------+
-    | status        | integer |           | not null |                                              |
-    +---------------+---------+-----------+----------+----------------------------------------------+
-    | person_id     | integer |           | not null |                                              |
-    +---------------+---------+-----------+----------+----------------------------------------------+
-    Indexes:
-        "timeseries_roles_pkey" PRIMARY KEY, btree (id)
-        "timeseries_roles_role_person_id_uniq" UNIQUE CONSTRAINT, btree (role, person_id)
-        "timeseries_roles_person_id" btree (person_id)
-    Check constraints:
-        "timeseries_roles_role_check" CHECK (role >= 0)
-        "timeseries_roles_status_check" CHECK (status >= 0)
-    Foreign-key constraints:
-        "timeseries_roles_person_id_3e26200e_fk_persons_id" FOREIGN KEY (person_id) REFERENCES persons(id) DEFERRABLE INITIALLY DEFERRED
-    """
-
-    __tablename__ = 'timeseries_roles'
-    __table_args__ = (
-        CheckConstraint('role >= 0'),
-        CheckConstraint('status >= 0'),
-        UniqueConstraint('role', 'person_id'),
-        {'extend_existing': True}
-    )
-
-    id = Column(Integer, primary_key=True, server_default=text("nextval('timeseries_roles_id_seq'::regclass)"))
-    role = Column(Integer, nullable=False)
-    status = Column(Integer, nullable=False)
-# do not use string declaration here (not working for pytest)
-# use the explicit class name here,
-# see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
-    person_id = Column(ForeignKey(Person.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
-    person = relationship(Person)
-
-    timeseries = relationship("Timeseries",
-        secondary=timeseries_timeseries_roles_table,
-        backref="roles")
+from toardb.base import Base
 
 
 class Timeseries(Base):
diff --git a/toardb/timeseries/models_programme.py b/toardb/timeseries/models_programme.py
index ce84b2d961a503bd07d3dada9568d46fd0e85da0..d293905a436ba0a54d97c900137c24cd359672c1 100644
--- a/toardb/timeseries/models_programme.py
+++ b/toardb/timeseries/models_programme.py
@@ -3,12 +3,15 @@
 class TimeseriesProgramme (Base)
 ================================
 """
-from sqlalchemy import Column, Integer, text, String, Text 
-from sqlalchemy.ext.declarative import declarative_base
-
-Base = declarative_base()
-metadata = Base.metadata
+from sqlalchemy import Column, Integer, text, String, Text, ForeignKey, Table
+from sqlalchemy.orm import relationship
+from toardb.base import Base
 
+# many-to-many relationships
+timeseries_timeseries_programmes_table = Table('timeseries_timeseries_programmes', Base.metadata,
+    Column('timeseries_id', Integer, ForeignKey('timeseries.id')),
+    Column('programme_id', Integer, ForeignKey('timeseries_programmes.id'))
+)
 
 # this has at the moment no relation to anything!!!
 class TimeseriesProgramme(Base):
@@ -38,3 +41,7 @@ class TimeseriesProgramme(Base):
     homepage = Column(String(200), nullable=False)
     description = Column(Text, nullable=False)
 
+    timeseries = relationship("Timeseries",
+        secondary=timeseries_timeseries_programmes_table,
+        backref="programmes")
+
diff --git a/toardb/timeseries/models_role.py b/toardb/timeseries/models_role.py
new file mode 100644
index 0000000000000000000000000000000000000000..fbfa87981337cba805b1d0ab18f85d4b786ca6c5
--- /dev/null
+++ b/toardb/timeseries/models_role.py
@@ -0,0 +1,64 @@
+# coding: utf-8
+"""
+class TimeseriesRole (Base)
+===========================
+"""
+from sqlalchemy import Column, ForeignKey, Integer, text, \
+                       CheckConstraint, UniqueConstraint, \
+                       Table
+from sqlalchemy.orm import relationship
+from toardb.contacts.models import Person
+from toardb.base import Base
+
+
+# many-to-many relationships
+timeseries_timeseries_roles_table = Table('timeseries_timeseries_roles', Base.metadata,
+    Column('timeseries_id', Integer, ForeignKey('timeseries.id')),
+    Column('role_id', Integer, ForeignKey('timeseries_roles.id'))
+)
+
+
+class TimeseriesRole(Base):
+    """ Table "public.timeseries_roles"
+
+    +---------------+---------+-----------+----------+----------------------------------------------+
+    |    Column     |  Type   | Collation | Nullable |                   Default                    |
+    +===============+=========+===========+==========+==============================================+
+    | id            | integer |           | not null | nextval('timeseries_roles_id_seq'::regclass) |
+    +---------------+---------+-----------+----------+----------------------------------------------+
+    | role          | integer |           | not null |                                              |
+    +---------------+---------+-----------+----------+----------------------------------------------+
+    | status        | integer |           | not null |                                              |
+    +---------------+---------+-----------+----------+----------------------------------------------+
+    | person_id     | integer |           | not null |                                              |
+    +---------------+---------+-----------+----------+----------------------------------------------+
+    Indexes:
+        "timeseries_roles_pkey" PRIMARY KEY, btree (id)
+        "timeseries_roles_role_person_id_uniq" UNIQUE CONSTRAINT, btree (role, person_id)
+        "timeseries_roles_person_id" btree (person_id)
+    Check constraints:
+        "timeseries_roles_role_check" CHECK (role >= 0)
+        "timeseries_roles_status_check" CHECK (status >= 0)
+    Foreign-key constraints:
+        "timeseries_roles_person_id_3e26200e_fk_persons_id" FOREIGN KEY (person_id) REFERENCES persons(id) DEFERRABLE INITIALLY DEFERRED
+    """
+
+    __tablename__ = 'timeseries_roles'
+    __table_args__ = (
+        CheckConstraint('role >= 0'),
+        CheckConstraint('status >= 0'),
+        UniqueConstraint('role', 'person_id')
+    )
+
+    id = Column(Integer, primary_key=True, server_default=text("nextval('timeseries_roles_id_seq'::regclass)"))
+    role = Column(Integer, nullable=False)
+    status = Column(Integer, nullable=False)
+# do not use string declaration here (not working for pytest)
+# use the explicit class name here,
+# see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
+    person_id = Column(ForeignKey(Person.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
+    person = relationship(Person)
+
+    timeseries = relationship("Timeseries",
+        secondary=timeseries_timeseries_roles_table,
+        backref="roles")
diff --git a/toardb/timeseries/schemas.py b/toardb/timeseries/schemas.py
index 59aea875e41b4100aa48f56529d39fd842d1f328..0a21ebea5caa4d211732992ecffb8d476ddb4cb4 100644
--- a/toardb/timeseries/schemas.py
+++ b/toardb/timeseries/schemas.py
@@ -103,12 +103,16 @@ class TimeseriesProgramme(TimeseriesProgrammeBase):
 
 class TimeseriesBase(TimeseriesCoreBase):
     roles: List[TimeseriesRole] = None
+    annotations: List[TimeseriesAnnotation] = None
+    programmes: List[TimeseriesProgramme] = None
 
     class Config:
         orm_mode = True
 
 class TimeseriesCreate(TimeseriesCoreBase):
     roles: List[TimeseriesRoleBase] = None
+    annotations: List[TimeseriesAnnotation] = None
+    programmes: List[TimeseriesProgramme] = None
 
     class Config:
         orm_mode = True
diff --git a/toardb/timeseries/test_base.py b/toardb/timeseries/test_base.py
index 259b2b38f75a136f098aaf839e63e3796fad3631..0906f4b5e617430be4ec3d332ba897506af947cd 100644
--- a/toardb/timeseries/test_base.py
+++ b/toardb/timeseries/test_base.py
@@ -9,10 +9,6 @@ from sqlalchemy_utils import database_exists, create_database, drop_database
 
 from toardb.utils.database import DATABASE_URL
 from .models import Base
-from toardb.variables.models import Base as VariableBase
-from toardb.stationmeta.models import Base as StationmetaBase
-from toardb.auth_user.models import Base as AuthUserBase
-from toardb.contacts.models import Base as ContactBase
 from toardb.toardb import app
 from toardb.timeseries.timeseries import get_db
  
@@ -82,10 +78,6 @@ def create_test_database():
     fake_conn.commit()
     fake_cur.execute("CREATE SEQUENCE public.timeseries_id_seq AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1")
     fake_conn.commit()
-    AuthUserBase.metadata.create_all(_db_conn)  # Create the tables.
-    ContactBase.metadata.create_all(_db_conn)  # Create the tables.
-    VariableBase.metadata.create_all(_db_conn)  # Create the tables.
-    StationmetaBase.metadata.create_all(_db_conn)  # Create the tables.
     # just to show that tables are available now:
 #   fake_cur.execute("SELECT * FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema'")
 #   rows = fake_cur.fetchall()
@@ -106,11 +98,7 @@ def test_db_session():
 
     yield session
     # Drop all data after each test
-    for tbl in reversed(AuthUserBase.metadata.sorted_tables +  
-                        ContactBase.metadata.sorted_tables +  
-                        VariableBase.metadata.sorted_tables +  
-                        StationmetaBase.metadata.sorted_tables +   
-                        Base.metadata.sorted_tables):
+    for tbl in reversed(Base.metadata.sorted_tables):
         _db_conn.execute(tbl.delete())
     # put back the connection to the connection pool
     session.close()
diff --git a/toardb/timeseries/test_timeseries.py b/toardb/timeseries/test_timeseries.py
index 18633bf893a275813468ed0ea972baec068f23ec..37f74fe46203162bdff0120099593e36c9802ebf 100644
--- a/toardb/timeseries/test_timeseries.py
+++ b/toardb/timeseries/test_timeseries.py
@@ -128,7 +128,7 @@ class TestApps:
                           'measurement_method': 'UV absorption', 'sampling_height': 7.0,
                           'date_added': '2020-05-15T15:30:00+02:00', 'date_modified': '2020-05-16T09:30:00+02:00',
                           'station_id': 2, 'variable_id': 7,
-                          'additional_metadata':{}, 'roles': []}]
+                          'additional_metadata':{}, 'roles': [], 'annotations': [], 'programmes': []}]
         assert response.json() == expected_resp
 
 
@@ -150,7 +150,7 @@ class TestApps:
                          'measurement_method': 'UV absorption', 'sampling_height': 7.0,
                          'date_added': '2020-05-15T15:30:00+02:00', 'date_modified': '2020-05-16T09:30:00+02:00',
                          'station_id': 2, 'variable_id': 7,
-                         'additional_metadata':{}, 'roles': []}
+                         'additional_metadata':{}, 'roles': [], 'annotations': [], 'programmes': []}
         assert response.json() == expected_resp
 
 
@@ -192,7 +192,7 @@ class TestApps:
                          'measurement_method': 'UV absorption', 'sampling_height': 7.0,
                          'date_added': '2020-05-15T15:30:00+02:00', 'date_modified': '2020-05-16T09:30:00+02:00',
                          'station_id': 2, 'variable_id': 7,
-                         'additional_metadata':{}, 'roles': []}
+                         'additional_metadata':{}, 'roles': [], 'annotations': [], 'programmes': []}
         assert response.json() == expected_resp
 
                                                     
@@ -210,7 +210,6 @@ class TestApps:
                            "roles": [{"role": 0, "person_id": 3, "status": 0},{"role": 1, "person_id": 3, "status": 0}]}
                      }
                    )
-        print("I got:", response.json())
         expected_status_code = 200
         assert response.status_code == expected_status_code
         expected_resp = {'id': 2, 'label': 'CMA2', 'order': 1, 'access_rights': 0,
@@ -220,7 +219,8 @@ class TestApps:
                          'date_added': '2020-05-15T15:30:00+02:00', 'date_modified': '2020-05-16T09:30:00+02:00',
                          'station_id': 2, 'variable_id': 7,
                          'additional_metadata':{},
-                         'roles': [{'id': 1, 'person_id': 3, 'role': 0, 'status': 0}, {'id': 2, 'person_id': 3, 'role': 1, 'status': 0}]}
+                         'roles': [{'id': 1, 'person_id': 3, 'role': 0, 'status': 0}, {'id': 2, 'person_id': 3, 'role': 1, 'status': 0}],
+                         'annotations': [], 'programmes': []}
         assert response.json() == expected_resp
 
                                                     
diff --git a/toardb/variables/models.py b/toardb/variables/models.py
index 4d264d9d60bc84cf65d94a36ea07ea66fdf349bb..06a6511c165a7e825a05fade2d81cde7387746ba 100644
--- a/toardb/variables/models.py
+++ b/toardb/variables/models.py
@@ -3,10 +3,7 @@ from sqlalchemy import ARRAY, BigInteger, Boolean, CheckConstraint, Column, Date
 from sqlalchemy.orm import relationship
 from sqlalchemy.sql.sqltypes import NullType
 from sqlalchemy.dialects.postgresql import JSONB
-from sqlalchemy.ext.declarative import declarative_base
-
-Base = declarative_base()
-metadata = Base.metadata
+from toardb.base import Base
 
 
 class Variable(Base):