Database architecture
This page is in active development, some content may be inaccurate.
Model
At a high level the database model can be described in the image bellow.

Important things to note about the relationship:
- An 
environmentexists within a givennamespaceand always has a currentbuild - A 
buildbelongs to a particularenvironmentand has associatedcondapackageandbuildartfacts - A 
buildartifactis a way for the database to keep track of external resources for example s3 artifacts, filesystem directories, etc - A 
condapackageis a representation of a given Conda package which belongs to a givencondachannel - A 
specificationis the environment.yaml using inconda env create -f <environment.yaml> 
The following will generate the database model shown bellow. It was
generated from the examples/docker example. You'll see in the
command that we are excluding several tables. These tables are managed
by celery.
pip install eralchemy  # not available on conda-forge
eralchemy -i "postgresql+psycopg2://admin:password@localhost:5432/conda-store"  \
    -x celery_tasksetmeta celery_taskmeta kombu_queue kombu_message alembic_version \
    -o output.png

Migrations
conda-store relies on SQLAlchemy for ORM mapping, and on Alembic for DB migrations.
The procedure to modify the database is the following :
- First, modify the ORM Model according to the changes you want to make
 - edit the file 
conda-store-server/alembic.iniand replace the value for entrysqlalchemy.urlto match the connection URL of your database. 
For example (when postgres was started via Docker compose):
script_location = alembic
sqlalchemy.url = postgresql+psycopg2://postgres:password@localhost:5432/conda-store
- in your command line, run the following :
 
cd conda-store-server/conda_store_server
alembic revision --autogenerate -m "description of your changes"
- 
You should have a new file in
conda-store-server/conda_store_server/alembic/versions/. Review it thoroughly. It contains thealembicoperations (op) to actually modify the database, either when upgrading (upgradefunction) or downgrading (downgrade) - 
You can migrate your data within these
upgrade/downgradefunctions, for example : 
from alembic import op
# revision identifiers, used by Alembic.
revision = 'abcdef01234567'
down_revision = '987654321f0edc'
branch_labels = None
depends_on = None
def upgrade():
    # operations to modify the database structure
    # ...
    op.create_table(
        'new_table',
        Column('id', INTEGER, primary_key=True),
        Column('field1', VARCHAR(50), nullable=False),
        Column('field2', INTEGER),
        Column('timestamp', TIMESTAMP, server_default=func.now())
    )
    # ...
    op.execute('''INSERT INTO new_table (field1, field2)
                  SELECT field1, field2
                  FROM old_table''')
    # other operations to modify the database structure
    # ...
def downgrade():
    op.drop_table('new_table')
- Once you're sure about the changes generated, you can apply them by running :
 
alembic upgrade head
- Check your database : your changes should be reflected. If not, refer to Alembic's documentation.