3 DBIx::Class::Manual::SQLHackers::CREATE - DBIx::Class for SQL Hackers - CREATE
5 =head1 Table of Contents
9 =item L<Introduction|DBIx::Class::Manual::SQLHackers::Introduction>
13 =item L<INSERT|DBIx::Class::Manual::SQLHackers::INSERT>
15 =item L<SELECT|DBIx::Class::Manual::SQLHackers::SELECT>
17 =item L<UPDATE|DBIx::Class::Manual::SQLHackers::UPDATE>
19 =item L<DELETE|DBIx::Class::Manual::SQLHackers::DELETE>
21 =item L<BEGIN, COMMIT|DBIx::Class::Manual::SQLHackers::Transactions>
25 =head1 Database structure
27 To use DBIx::Class, we need to teach it about the layout of the underlying database. Several methods are supported. The built-in method involves defining your database structure as a set of perl classes, one per resultsource (table, view, etc). The other oft used method is to import the definitions from an existing database using the module
28 L<DBIx::Class::Schema::Loader>.
30 Once a DBIx::Class schema (set of classes describing the database) has been created, built-in methods can be used to export it as SQL DDL using L<SQL::Translator>.
34 Install L<DBIx::Class::Schema::Loader> and decide on a name for your schema classes.
36 Run the included L<dbicdump> script.
38 dbicdump -o dump_directory=./lib \
39 -o components='["InflateColumn::DateTime"]' \
41 MyApp::Schema dbi:mysql:database=foo user pass '{ quote_names => 1 }'
44 =head2 Manual Result class creation (and understanding Loader results)
46 This section covers the common and oft used CREATE DDL statements that DBIx::Class can replaces with Perl classes: B<CREATE TABLE>, B<CREATE VIEW> and B<CREATE INDEX>. The classes can be used to write the actual SQL DDL to the database or disc, if required.
50 =head4 Standard basic table creation in SQL:
53 id INTEGER AUTO_INCREMENT,
54 username VARCHAR(255),
56 realname VARCHAR(255),
60 We'll get to tables with references (foreign keys) later, here's the translation to DBIx::Class:
62 The recommended version:
64 package MyDatabase::Schema::Result::User;
68 use base 'DBIx::Class::Core';
70 __PACKAGE__->table('users');
71 __PACKAGE__->add_columns(
73 data_type => 'integer',
74 is_auto_increment => 1,
77 data_type => 'varchar',
84 data_type => 'varchar',
88 data_type => 'varchar',
92 __PACKAGE__->set_primary_key('id');
93 __PACKAGE__->add_unique_constraint('uniq_username' => ['username']);
96 The fully descriptive version is required if you want to have DBIx::Class create your CREATE TABLE sql for you later. Many DBIC components also use settings in the column info hashrefs to decide how to treat the data for those columns.
98 =head4 Table creation with references:
100 A relational database isn't worth much if we don't actually use references and constraints, so here is an example which constrains the B<user_id> column to only contain B<id> values from the *users* table.
103 id INTEGER AUTO_INCREMENT,
105 created_date DATETIME,
108 INDEX posts_idx_user_id (user_id),
110 CONSTRAINT posts_fk_user_id FOREIGN KEY (user_id) REFERENCES users (id)
113 In DBIx::Class this is achieved by adding L<relationship|DBIx::Class::Relationship> definitions to the class:
115 package MyDatabase::Schema::Result::Post;
118 use base 'DBIx::Class::Core';
120 __PACKAGE__->table('posts');
121 __PACKAGE__->add_columns(
123 data_type => 'integer',
124 is_auto_increment => 1,
127 data_type => 'integer',
130 data_type => 'datetime',
133 data_type => 'varchar',
141 __PACKAGE__->set_primary_key('id');
142 __PACKAGE__->belongs_to('user', 'MyDatabase::Schema::Result::User', 'user_id');
145 The B<belongs_to> relation creates a B<user> method which returns the user object, as well as storing JOIN information to be used when querying with JOINs. The joined colums on the remote side are taken from the remote PRIMARY KEY value, if not specified, as in this example.
147 Relationships may also be specified with completely custom JOIN conditions, using any columns, whether the database has them defined as constraints or not, or literal values.
149 To allow access from the B<user> object back to the posts they have written, we need to define another relationship in the User class:
151 __PACKAGE__->has_many('posts', 'MyDatabase::Schema::Result::Post', 'user_id');
155 In SQL, a simple view that returns all users and their posts:
157 CREATE VIEW userposts
159 SELECT posts.user_id, users.username, users.dob, users.realname, posts.createddate, posts.title, posts.post
161 JOIN posts ON (users.id = posts.user_id)
163 In DBIx::Class this can have a Result Class of its own:
165 package MyDatabase::Schema::Result::UserPosts;
167 use base qw/DBIx::Class::Core/;
169 # Defaults to 'DBIx::Class::ResultSource::Table' unless specified like this
170 __PACKAGE__->table_class('DBIx::Class::ResultSource::View');
172 __PACKAGE__->table('user_posts');
174 # Do not emit SQL DDL for this particular resultsource
175 __PACKAGE__->result_source_instance->is_virtual(1);
177 __PACKAGE__->result_source_instance->view_definition(
178 "SELECT posts.user_id, users.username, users.dob, users.realname, posts.createddate, posts.title, posts.post
180 JOIN posts ON (users.id = posts.user_id)"
182 __PACKAGE__->add_columns(
184 data_type => 'integer',
187 data_type => 'varchar',
194 data_type => 'varchar',
198 data_type => 'datetime',
201 data_type => 'varchar',
209 __PACKAGE__->set_primary_key('user_id, post_id');
213 =head4 UNIQUE indexes
215 CREATE UNIQUE INDEX username_idx ON user (username);
217 To add extra unique indexes, add the B<add_unique_constraint> call to your Result Class.
219 __PACKAGE__->add_unique_constraint('username_idx' => ['username']);
221 =head3 Outputting SQL DDL
223 Once the DBIC schema has been defined, you can outout the SQL DDL needed to create the schema in your database (using the RDBMS-specific flavor of SQL DDL) in one of several ways.
225 =head4 Deploy directly to the database
227 Create a schema object with the correct database connection, then call B<deploy> on it.
229 my $schema = MyDatabase::Schema->connect('dbi:SQLite:my.db');
230 $schema->deploy({add_drop_table => 1});
232 L<DBIx::Class::Schema/deploy> has the documentation for the deploy method.
234 =head4 Write out SQL files
236 Create a schema object with the a database connection (any will do), and call the B<create_ddl_dir> method on it.
238 my $schema = MyDatabase::Schema->connect('dbi:SQLite:my.db');
239 $schema->create_ddl_dir(['SQLite', 'MySQL']);
241 If called with no arguments, this method will create an SQL file each for MySQL, PostgreSQL and SQLite. More databases are supported by L<SQL::Translator> if necessary.
243 =head4 SQL files for upgrades (ALTER TABLE)
245 DBIC can also make use of L<SQL::Translator::Diff> to write out ALTER TABLE statements when the schema classes are changed.
247 To do this, make sure that you set a B<$VERSION> in your main Schema class, and run B<create_ddl_dir> on the initial version to provide a baseline.
249 After the schema has changed, change the B<$VERSION> value and re-run B<create_ddl_dir>.
251 my $schema = MyDatabase::Schema->connect('dbi:SQLite:my.db');
252 $schema->create_ddl_dir(\@databases, undef, '.', '0.1');