Create MySQL Tables with Ansible - mysql

I'm using ansible to manage a small mail server using ubuntu. I wanted to use ansible to create a database which I can do and also create users for the database(s) which I can do also. But I'm not sure how to create tables using ansible. I'm trying to create the following three MySQL tables using ansible:
1)
CREATE TABLE `virtual_domains` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
2)
CREATE TABLE `virtual_users` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`password` varchar(106) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3)
CREATE TABLE `virtual_aliases` (
`id` int(11) NOT NULL auto_increment,
`domain_id` int(11) NOT NULL,
`source` varchar(100) NOT NULL,
`destination` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
FOREIGN KEY (domain_id) REFERENCES virtual_domains(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I have searched and searched and even ask in #ansible and have stated that I can use the mysql_db module to complete the above task but I can't find any examples that will give me some type of direction on how to achieve the above in ansible.
Any and all help would be GREATLY appreciated!

With the mysql_db module you can import a MySQL file. So you can simply copy all 3 create statements into one singly text file and import it like this:
- mysql_db: name=my_db state=import target=/tmp/dump.sql.bz2
That example is taken from the above linked docs page, there are more tasks including one which shows you how to copy the file to the host before.

hosts: mysql
tasks:
name: create a table in mysql_databases
command: mysql -u root -p[root1234] testdb --skip-column-names --execute "create table test_table (Name varchar(255), EmpID INT NOT NULL)"

Related

text type in mysql primary keyed and unique by default

I have created some tables in mysql database and I don't understand why all of the text types are primary keyed and unique by default.
Anyone got any idea?
This is the query I got from phpmyadmin:
CREATE TABLE temp (
id int(11) NOT NULL AUTO_INCREMENT,
random varchar(25) DEFAULT NULL,
history text, PRIMARY KEY (id) )
ENGINE=InnoDB DEFAULT CHARSET=latin1

How do i enable EER Model in MYSQL 6.3 workbench ? or How can i create foreign key for my "offers" table?

These are my tables users and offers
users
name username email password authority enabled
offers
id text
But i want to create a foreign key in my offers table from the column name "username" in my users table. How do i do it with my sql workbench 6.3 ? or how do i enable EER model for my tables ?
These are create statement for the two tables.
offer table
CREATE TABLE `offer` (
`id` int(11) NOT NULL,
`text` varchar(45) DEFAULT NULL,
`username_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `username_id_idx` (`username_id`),
CONSTRAINT `username_id` FOREIGN KEY (`username_id`) REFERENCES `user` (`iduser`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
user table
CREATE TABLE `user` (
`iduser` int(11) NOT NULL,
`username` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`password` varchar(45) DEFAULT NULL,
`authority` varchar(45) DEFAULT NULL,
`enabled` varchar(45) DEFAULT NULL,
PRIMARY KEY (`iduser`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
If you are using Workbench 6.3 you can check the EER diagram by :
Database - > Reverse Engineer - > Select a connection - > Select the scheme you want to see.
Hope this helps!

MySQL to Postgres syntax

I am working on a maven project and for that I am using Postgres as database. Unfortunately the database I know more is MySQL. I have the basic details of SQL file which I want to include in the database. If possible, can someone with knowledge of postgres help me to convert the syntax. One more question, for maven project, do I need to include the .sql file within the project(if yes, where). Kindly let me know.
person.sql.
CREATE TABLE `Person` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT '',
`country` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
Thank you.
CREATE TABLE Person
(
id bigserial NOT NULL primary key,
name varchar(20) NOT NULL DEFAULT '',
country varchar(20) DEFAULT NULL
);
More details in the manual: http://www.postgresql.org/docs/current/static/sql-createtable.html

MySQL Create table with reference to non existant table

Using MySQL workbench, I copied the create statement from a few related tables to put into a clean schema. They all reference each other in some way so there is no inherent order I can create them in. How can I just force MySQL to create the tables while ignoring any warning that may occur, just until the rest of the tables are created?
Would I have to group it inside a transaction of some sort?
A very simple example would be:
CREATE TABLE `vehicle` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`gallery_id` int(11) DEFAULT NULL,
`make_id` int(11) NOT NULL,
`model_id` int(11) DEFAULT NULL,
`make` varchar(100) DEFAULT '',
`model` varchar(100) DEFAULT '',
`colour_id` int(11) DEFAULT NULL,
`currency_id` int(11) NOT NULL DEFAULT '1',
`fuel_id` int(11) DEFAULT NULL,
`status_id` int(11) DEFAULT NULL,
`stock_code` varchar(100) DEFAULT NULL,
`registration` varchar(20) DEFAULT NULL,
`title` varchar(100) DEFAULT NULL,
`description` text,
`month` tinyint(4) DEFAULT NULL,
`public` tinyint(4) NOT NULL DEFAULT '0',
`sold` tinyint(4) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `vehicle_fk_idx` (`status_id`),
CONSTRAINT `vehicle_fk` FOREIGN KEY (`status_id`) REFERENCES `vehicle_status` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `vehicle_status` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`slug` varchar(100) DEFAULT NULL,
`title` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `slug_UNIQUE` (`slug`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
vehicle references vehicle_status which would mean that vehicle_status would have to be created first. How would I create vehicle first and then vehicle_status without adding the reference afterwards?
You do not define foreign keys when creating tables, you would have them in a separate query like this:
ALTER TABLE `vehicle`
ADD CONSTRAINT `vehicle_ibfk_1` FOREIGN KEY (`status_id`)
REFERENCES `vehicle_status` (`id`) ON DELETE SET NULL ON UPDATE CASCADE;
So you would first create tables and then create foreign keys.
The way I personally do is I have all CREATE TABLE queries in one file that I know I can simply just import without any errors. I have all CONSTRAINT queries in a separate file that I import after all the tables have been created and I have all INSERT INTO queries in a separate file that adds data after all constraints and tables have been set.
It looks like vehicle_status is a lookup table, while vehicle is a primary transaction table.
In general, lookup tables do not reference other tables, although there can be designs where one lookup table references another lookup table. In your case, it's simple: just create vehicle_status first. If your schema has a hundred tables in it, it's going to involve a little work to order the create commands in the right sequence.
There are designs where the reference chain forms a circle. In such a case, you'll have to do what GGio suggests: add the constraints later. There are other problems with designs involving circular references, and those problems may or may not be present in your schema.
When you go to populate the tables, you'll have to worry about order as well. In general, you'll have to populate the lookup tables first, before you begin to populate the transaction tables. Otherwise you'll get reference violations at load time.

MySQL foreign keys' referenced table name always forced to lowercase

First, create these two tables:
CREATE TABLE IF NOT EXISTS TAB_COMPANY (
ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
NAME VARCHAR(100) NOT NULL,
PRIMARY KEY(ID),
UNIQUE KEY(NAME)
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
CREATE TABLE IF NOT EXISTS TAB_DEPARTMENT (
ID INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
NAME VARCHAR(100) NOT NULL,
COMPANYID INT(10) UNSIGNED NOT NULL,
PRIMARY KEY(ID),
INDEX FK_TAB_DEPARTMENT_TAB_COMPANY_COMPANYID(COMPANYID ASC),
CONSTRAINT FK_TAB_DEPARTMENT_TAB_COMPANY_COMPANYID
FOREIGN KEY (COMPANYID) REFERENCES TAB_COMPANY(ID) ON DELETE CASCADE
) ENGINE=INNODB DEFAULT CHARSET=UTF8;
Then show create table TAB_DEPARTMENT:
CREATE TABLE `TAB_DEPARTMENT` (
`ID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`NAME` varchar(100) NOT NULL,
`COMPANYID` int(10) unsigned NOT NULL,
PRIMARY KEY (`ID`),
KEY `FK_TAB_DEPARTMENT_TAB_COMPANY_COMPANYID` (`COMPANYID`),
CONSTRAINT `FK_TAB_DEPARTMENT_TAB_COMPANY_COMPANYID` FOREIGN KEY (`COMPANYID`)
REFERENCES `tab_company` (`ID`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8
The table name in foreign key reference clause is forced to lower case.
mysql> show variables like '%lower%';
lower_case_file_system ON
lower_case_table_names 0
mysql> show variables like 'version';
version 5.1.43-community
My platform is Window XP with SP3. I tested this on Linux, it is OK.
Has anyone encountered this issue before? I already reported a bug to MySQL.
I just tried on version 5.1.49-community, and the issue is still there.
Got the reply from MySQL:
From Miguel Solorzano:
Thank you for the bug report. This a documented restriction of InnoDB
table:
http://dev.mysql.com/doc/refman/5.1/en/innodb-restrictions.html
"On Windows, InnoDB always stores database and table names internally
in lowercase. To move databases in a binary format from Unix to Windows
or from Windows to Unix, you should create all databases and tables
using lowercase names. "