Move rendering of attachment to macro
[cds-indico.git] / DEVELOPMENT.md
blobee896289c19c0536c326340057efd419cf106b39
1 Tips for developers
2 -------------------
3 It's dangerous to go alone. Take these tips in case you need to fit Indico to your particular needs.
5 ## SQLAlchemy
6 For the moment, we are focusing on _PostgreSQL_. These are some of the specific calls that you'd need to change in case
7 you want to use a different relational database such as MySQL (don't do it, you will spend much more time on it than
8 installing PostgreSQL would take!):
10 * `array_agg()`, since MySQL doesn't have ARRAY type. You can find occurrences of them within:
11     - _indico/modules/rb/models/locations.py_
12     - _indico/modules/rb/models/rooms.py_
14 * ReservationEditLog uses a PostgreSQL ARRAY to store the changes for a single log entry
16 * calculate_rooms_booked_time uses `extract('dow')` PostgreSQL specific for day of the week.
18 In some cases you have properties in your models which trigger additional queries or are expensive for some other reason.
19 Sometimes you can simply write tricky queries to retrieve all data at once, but in other cases that's not feasible,
20 either because of what the property does or because you need it for serializing and thus only have the object itself
21 available.  But caching is easy: Simply use the `@cached` decorator from `indico.modules.rb.models.utils` combined with
22 the `versioned_cache` mixin. For details, see the docstrings of these functions.
25 ## Initializing the database
26 Use `indico db prepare` to create your tables based on the SQLAlchemy models and set the migration status to the most
27 recent alembic revision.
29 If you want to import data from ZODB, run `bin/migration/migrate_to_sqlalchemy.py` with the appropriate arguments.
32 ## SQL Database migrations
33 Whenever you modify the database structure or want to perform data migrations, create an alembic revision.
34 To do so, use `indico db revision -m 'short explanation'`; optionally you may specify `--autogenerate` to let Alembic
35 compare your SQLAlchemy models with your database and generate migrations automatically. However, this is not 100%
36 reliable and for example functional indexes will always show up as "new". So if you use autogeneration, **always**
37 check the generated migration steps and modify them if necessary. Especially if you've already applied your change to the
38 database manually or let SQLAlchemy create your new table you need to write the migration for it manually or DROP the
39 table again so Alembic knows it's new.
41 To perform the actual migration of the database, run `indico db upgrade` or `indico db downgrade`. Migration should
42 always be possible in both directions, so when writing a migration step make sure to test it and to implement both
43 directions for structure and data even if that means dropping columns or tables. Losing data during a downgrade is
44 acceptable as long as it's data that didn't exist before that revision. Please make sure to TEST migration in both
45 directions!
47 When adding a new column that is not nullable, you need to add it in two steps: First create it with a `server_default`
48 value set to whatever default value you want. Afterwars, use the `alter_column` operation to remove the default value.
49 While keeping it would not hurt, it's better to stay in sync with the SQLAlchemy model!