diff --git a/app/models.py b/app/models.py
index 320544ada86c49cbae3324b8371f920978c0371e..e4ff1733f89b826ec16507c7bb04bd39a1e2b950 100644
--- a/app/models.py
+++ b/app/models.py
@@ -250,6 +250,28 @@ class AnonymousUser(AnonymousUserMixin):
         return False
 
 
+class JobInput(db.Model):
+    """
+    Class to define Files.
+    """
+    __tablename__ = 'job_inputs'
+    # Primary key
+    id = db.Column(db.Integer, primary_key=True)
+    filename = db.Column(db.String(255))
+    job_id = db.Column(db.Integer, db.ForeignKey('jobs.id'))
+
+
+class JobResult(db.Model):
+    """
+    Class to define Files.
+    """
+    __tablename__ = 'job_results'
+    # Primary key
+    id = db.Column(db.Integer, primary_key=True)
+    filename = db.Column(db.String(255))
+    job_id = db.Column(db.Integer, db.ForeignKey('jobs.id'))
+
+
 class Job(db.Model):
     """
     Class to define Jobs.
@@ -272,6 +294,15 @@ class Job(db.Model):
     status = db.Column(db.String(16))
     title = db.Column(db.String(32))
     user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
+    # Relationships
+    inputs = db.relationship('JobInput',
+                             backref='job',
+                             lazy='dynamic',
+                             cascade='save-update, merge, delete')
+    results = db.relationship('JobResult',
+                              backref='job',
+                              lazy='dynamic',
+                              cascade='save-update, merge, delete')
 
     def __init__(self, **kwargs):
         super(Job, self).__init__(**kwargs)
@@ -329,6 +360,17 @@ class Job(db.Model):
         db.session.commit()
 
 
+class CorpusFile(db.Model):
+    """
+    Class to define Files.
+    """
+    __tablename__ = 'corpus_files'
+    # Primary key
+    id = db.Column(db.Integer, primary_key=True)
+    filename = db.Column(db.String(255))
+    corpus_id = db.Column(db.Integer, db.ForeignKey('corpora.id'))
+
+
 class Corpus(db.Model):
     """
     Class to define a corpus.
@@ -340,6 +382,11 @@ class Corpus(db.Model):
     description = db.Column(db.String(255))
     title = db.Column(db.String(32))
     user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
+    # Relationships
+    files = db.relationship('CorpusFile',
+                            backref='relation',
+                            lazy='dynamic',
+                            cascade='save-update, merge, delete')
 
     def __init__(self, **kwargs):
         super(Corpus, self).__init__(**kwargs)
diff --git a/app/services/views.py b/app/services/views.py
index f5ff17802bde6040c9cf4b521557b1a56c46b160..528545a2315390dd60bd51e578ef554248382784 100644
--- a/app/services/views.py
+++ b/app/services/views.py
@@ -1,9 +1,10 @@
 from flask import abort, current_app, flash, redirect, render_template, url_for
-from . import services
 from flask_login import current_user, login_required
+from werkzeug.utils import secure_filename
+from . import services
 from .forms import NewNLPJobForm, NewOCRJobForm
-from ..models import Job
 from .. import db
+from ..models import Job, JobInput
 import json
 import os
 
@@ -53,7 +54,10 @@ def service(service_handle):
         else:
             for file in new_job_form.files.data:
                 ''' TODO: Use secure filename '''
-                file.save(os.path.join(dir, file.filename))
+                filename = secure_filename(file.filename)
+                file.save(os.path.join(dir, filename))
+                job_input = JobInput(filename=filename, job=job)
+                db.session.add(job_input)
             job.status = 'submitted'
             db.session.commit()
             flash('Job created!')
diff --git a/migrations/README b/migrations/README
deleted file mode 100644
index 98e4f9c44effe479ed38c66ba922e7bcc672916f..0000000000000000000000000000000000000000
--- a/migrations/README
+++ /dev/null
@@ -1 +0,0 @@
-Generic single-database configuration.
\ No newline at end of file
diff --git a/migrations/alembic.ini b/migrations/alembic.ini
deleted file mode 100644
index f8ed4801f78bcb83cc6acb589508c1b24eda297a..0000000000000000000000000000000000000000
--- a/migrations/alembic.ini
+++ /dev/null
@@ -1,45 +0,0 @@
-# A generic, single database configuration.
-
-[alembic]
-# template used to generate migration files
-# file_template = %%(rev)s_%%(slug)s
-
-# set to 'true' to run the environment during
-# the 'revision' command, regardless of autogenerate
-# revision_environment = false
-
-
-# Logging configuration
-[loggers]
-keys = root,sqlalchemy,alembic
-
-[handlers]
-keys = console
-
-[formatters]
-keys = generic
-
-[logger_root]
-level = WARN
-handlers = console
-qualname =
-
-[logger_sqlalchemy]
-level = WARN
-handlers =
-qualname = sqlalchemy.engine
-
-[logger_alembic]
-level = INFO
-handlers =
-qualname = alembic
-
-[handler_console]
-class = StreamHandler
-args = (sys.stderr,)
-level = NOTSET
-formatter = generic
-
-[formatter_generic]
-format = %(levelname)-5.5s [%(name)s] %(message)s
-datefmt = %H:%M:%S
diff --git a/migrations/env.py b/migrations/env.py
deleted file mode 100644
index 79b8174be8a33bf4aaa610a4bab01dbd7bee9d80..0000000000000000000000000000000000000000
--- a/migrations/env.py
+++ /dev/null
@@ -1,96 +0,0 @@
-from __future__ import with_statement
-
-import logging
-from logging.config import fileConfig
-
-from sqlalchemy import engine_from_config
-from sqlalchemy import pool
-
-from alembic import context
-
-# this is the Alembic Config object, which provides
-# access to the values within the .ini file in use.
-config = context.config
-
-# Interpret the config file for Python logging.
-# This line sets up loggers basically.
-fileConfig(config.config_file_name)
-logger = logging.getLogger('alembic.env')
-
-# add your model's MetaData object here
-# for 'autogenerate' support
-# from myapp import mymodel
-# target_metadata = mymodel.Base.metadata
-from flask import current_app
-config.set_main_option(
-    'sqlalchemy.url', current_app.config.get(
-        'SQLALCHEMY_DATABASE_URI').replace('%', '%%'))
-target_metadata = current_app.extensions['migrate'].db.metadata
-
-# other values from the config, defined by the needs of env.py,
-# can be acquired:
-# my_important_option = config.get_main_option("my_important_option")
-# ... etc.
-
-
-def run_migrations_offline():
-    """Run migrations in 'offline' mode.
-
-    This configures the context with just a URL
-    and not an Engine, though an Engine is acceptable
-    here as well.  By skipping the Engine creation
-    we don't even need a DBAPI to be available.
-
-    Calls to context.execute() here emit the given string to the
-    script output.
-
-    """
-    url = config.get_main_option("sqlalchemy.url")
-    context.configure(
-        url=url, target_metadata=target_metadata, literal_binds=True
-    )
-
-    with context.begin_transaction():
-        context.run_migrations()
-
-
-def run_migrations_online():
-    """Run migrations in 'online' mode.
-
-    In this scenario we need to create an Engine
-    and associate a connection with the context.
-
-    """
-
-    # this callback is used to prevent an auto-migration from being generated
-    # when there are no changes to the schema
-    # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
-    def process_revision_directives(context, revision, directives):
-        if getattr(config.cmd_opts, 'autogenerate', False):
-            script = directives[0]
-            if script.upgrade_ops.is_empty():
-                directives[:] = []
-                logger.info('No changes in schema detected.')
-
-    connectable = engine_from_config(
-        config.get_section(config.config_ini_section),
-        prefix='sqlalchemy.',
-        poolclass=pool.NullPool,
-    )
-
-    with connectable.connect() as connection:
-        context.configure(
-            connection=connection,
-            target_metadata=target_metadata,
-            process_revision_directives=process_revision_directives,
-            **current_app.extensions['migrate'].configure_args
-        )
-
-        with context.begin_transaction():
-            context.run_migrations()
-
-
-if context.is_offline_mode():
-    run_migrations_offline()
-else:
-    run_migrations_online()
diff --git a/migrations/script.py.mako b/migrations/script.py.mako
deleted file mode 100644
index 2c0156303a8df3ffdc9de87765bf801bf6bea4a5..0000000000000000000000000000000000000000
--- a/migrations/script.py.mako
+++ /dev/null
@@ -1,24 +0,0 @@
-"""${message}
-
-Revision ID: ${up_revision}
-Revises: ${down_revision | comma,n}
-Create Date: ${create_date}
-
-"""
-from alembic import op
-import sqlalchemy as sa
-${imports if imports else ""}
-
-# revision identifiers, used by Alembic.
-revision = ${repr(up_revision)}
-down_revision = ${repr(down_revision)}
-branch_labels = ${repr(branch_labels)}
-depends_on = ${repr(depends_on)}
-
-
-def upgrade():
-    ${upgrades if upgrades else "pass"}
-
-
-def downgrade():
-    ${downgrades if downgrades else "pass"}
diff --git a/migrations/versions/685dff1cc01b_initial_migration.py b/migrations/versions/685dff1cc01b_initial_migration.py
deleted file mode 100644
index bb16ab81c303740b042477a534b424421f69b621..0000000000000000000000000000000000000000
--- a/migrations/versions/685dff1cc01b_initial_migration.py
+++ /dev/null
@@ -1,80 +0,0 @@
-"""initial migration
-
-Revision ID: 685dff1cc01b
-Revises: 
-Create Date: 2019-09-13 07:31:57.149510
-
-"""
-from alembic import op
-import sqlalchemy as sa
-
-
-# revision identifiers, used by Alembic.
-revision = '685dff1cc01b'
-down_revision = None
-branch_labels = None
-depends_on = None
-
-
-def upgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.create_table('roles',
-    sa.Column('id', sa.Integer(), nullable=False),
-    sa.Column('default', sa.Boolean(), nullable=True),
-    sa.Column('name', sa.String(length=64), nullable=True),
-    sa.Column('permissions', sa.Integer(), nullable=True),
-    sa.PrimaryKeyConstraint('id'),
-    sa.UniqueConstraint('name')
-    )
-    op.create_index(op.f('ix_roles_default'), 'roles', ['default'], unique=False)
-    op.create_table('users',
-    sa.Column('id', sa.Integer(), nullable=False),
-    sa.Column('confirmed', sa.Boolean(), nullable=True),
-    sa.Column('email', sa.String(length=254), nullable=True),
-    sa.Column('password_hash', sa.String(length=128), nullable=True),
-    sa.Column('registration_date', sa.DateTime(), nullable=True),
-    sa.Column('role_id', sa.Integer(), nullable=True),
-    sa.Column('username', sa.String(length=64), nullable=True),
-    sa.ForeignKeyConstraint(['role_id'], ['roles.id'], ),
-    sa.PrimaryKeyConstraint('id')
-    )
-    op.create_index(op.f('ix_users_email'), 'users', ['email'], unique=True)
-    op.create_index(op.f('ix_users_username'), 'users', ['username'], unique=True)
-    op.create_table('corpora',
-    sa.Column('id', sa.Integer(), nullable=False),
-    sa.Column('creation_date', sa.DateTime(), nullable=True),
-    sa.Column('description', sa.String(length=255), nullable=True),
-    sa.Column('title', sa.String(length=32), nullable=True),
-    sa.Column('user_id', sa.Integer(), nullable=True),
-    sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
-    sa.PrimaryKeyConstraint('id')
-    )
-    op.create_table('jobs',
-    sa.Column('id', sa.Integer(), nullable=False),
-    sa.Column('creation_date', sa.DateTime(), nullable=True),
-    sa.Column('description', sa.String(length=255), nullable=True),
-    sa.Column('end_date', sa.DateTime(), nullable=True),
-    sa.Column('mem_mb', sa.Integer(), nullable=True),
-    sa.Column('n_cores', sa.Integer(), nullable=True),
-    sa.Column('service', sa.String(length=64), nullable=True),
-    sa.Column('service_args', sa.String(length=255), nullable=True),
-    sa.Column('service_version', sa.String(length=16), nullable=True),
-    sa.Column('status', sa.String(length=16), nullable=True),
-    sa.Column('title', sa.String(length=32), nullable=True),
-    sa.Column('user_id', sa.Integer(), nullable=True),
-    sa.ForeignKeyConstraint(['user_id'], ['users.id'], ),
-    sa.PrimaryKeyConstraint('id')
-    )
-    # ### end Alembic commands ###
-
-
-def downgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.drop_table('jobs')
-    op.drop_table('corpora')
-    op.drop_index(op.f('ix_users_username'), table_name='users')
-    op.drop_index(op.f('ix_users_email'), table_name='users')
-    op.drop_table('users')
-    op.drop_index(op.f('ix_roles_default'), table_name='roles')
-    op.drop_table('roles')
-    # ### end Alembic commands ###
diff --git a/migrations/versions/f16b80c57038_.py b/migrations/versions/f16b80c57038_.py
deleted file mode 100644
index 45c90f94f071c0eef1a1e443d51e567c259666b8..0000000000000000000000000000000000000000
--- a/migrations/versions/f16b80c57038_.py
+++ /dev/null
@@ -1,28 +0,0 @@
-"""empty message
-
-Revision ID: f16b80c57038
-Revises: 685dff1cc01b
-Create Date: 2019-10-09 09:34:37.616747
-
-"""
-from alembic import op
-import sqlalchemy as sa
-
-
-# revision identifiers, used by Alembic.
-revision = 'f16b80c57038'
-down_revision = '685dff1cc01b'
-branch_labels = None
-depends_on = None
-
-
-def upgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.add_column('users', sa.Column('is_dark', sa.Boolean(), nullable=True))
-    # ### end Alembic commands ###
-
-
-def downgrade():
-    # ### commands auto generated by Alembic - please adjust! ###
-    op.drop_column('users', 'is_dark')
-    # ### end Alembic commands ###