changing the things to document in api.rst
[mediagoblin.git] / docs / source / pluginwriter / database.rst
1 .. MediaGoblin Documentation
2
3 Written in 2013 by MediaGoblin contributors
4
5 To the extent possible under law, the author(s) have dedicated all
6 copyright and related and neighboring rights to this software to
7 the public domain worldwide. This software is distributed without
8 any warranty.
9
10 You should have received a copy of the CC0 Public Domain
11 Dedication along with this software. If not, see
12 <http://creativecommons.org/publicdomain/zero/1.0/>.
13
14
15 ========
16 Database
17 ========
18
19
20 Accessing Existing Data
21 =======================
22
23 If your plugin wants to access existing data, this is quite
24 straight forward. Just import the appropiate models and use
25 the full power of SQLAlchemy. Take a look at the (upcoming)
26 database section in the Developer's Chapter.
27
28
29 Creating new Tables
30 ===================
31
32 If your plugin needs some new space to store data, you
33 should create a new table. Please do not modify core
34 tables. Not doing so might seem inefficient and possibly
35 is. It will help keep things sane and easier to upgrade
36 versions later.
37
38 So if you create a new plugin and need new tables, create a
39 file named ``models.py`` in your plugin directory. You
40 might take a look at the core's db.models for some ideas.
41 Here's a simple one:
42
43 .. code-block:: python
44
45 from mediagoblin.db.base import Base
46 from sqlalchemy import Column, Integer, Unicode, ForeignKey
47
48 class MediaSecurity(Base):
49 __tablename__ = "yourplugin__media_security"
50
51 # The primary key *and* reference to the main media_entry
52 media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
53 primary_key=True)
54 get_media_entry = relationship("MediaEntry",
55 backref=backref("security_rating", cascade="all, delete-orphan"))
56
57 rating = Column(Unicode)
58
59 MODELS = [MediaSecurity]
60
61 That's it.
62
63 Some notes:
64
65 * Make sure all your ``__tablename__`` start with your
66 plugin's name so the tables of various plugins can't
67 conflict in the database. (Conflicts in python naming are
68 much easier to fix later).
69 * Try to get your database design as good as possible in
70 the first attempt. Changing the database design later,
71 when people already have data using the old design, is
72 possible (see next chapter), but it's not easy.
73
74
75 Changing the Database Schema Later
76 ==================================
77
78 If your plugin is in use and instances use it to store some
79 data, changing the database design is a tricky thing.
80
81 1. Make up your mind how the new schema should look like.
82 2. Change ``models.py`` to contain the new schema. Keep a
83 copy of the old version around for your personal
84 reference later.
85 3. Now make up your mind (possibly using your old and new
86 ``models.py``) what steps in SQL are needed to convert
87 the old schema to the new one.
88 This is called a "migration".
89 4. Create a file ``migrations.py`` that will contain all
90 your migrations and add your new migration.
91
92 Take a look at the core's ``db/migrations.py`` for some
93 good examples on what you might be able to do. Here's a
94 simple one to add one column:
95
96 .. code-block:: python
97
98 from mediagoblin.db.migration_tools import RegisterMigration, inspect_table
99 from sqlalchemy import MetaData, Column, Integer
100
101 MIGRATIONS = {}
102
103 @RegisterMigration(1, MIGRATIONS)
104 def add_license_preference(db):
105 metadata = MetaData(bind=db.bind)
106
107 security_table = inspect_table(metadata, 'yourplugin__media_security')
108
109 col = Column('security_level', Integer)
110 col.create(security_table)
111 db.commit()