Web Application Development Practical7: MySQL
Practical session 7: MySQL
To do this practical you will need to have MySQL installed on your computer.
Warning: MySQL is a server and is not very tolerant of errors. Please make sure read and follow all parts of every instruction carefully and do not skip over any.
If you are using Windows, download the MySQL Installer from https://dev.mysql.com/downloads/installer/ . If you are using MacOS, download MySQL Community Server from https://dev.mysql.com/downloads/mysql/ . If you are using Linux, you can install MySQL through your Linux distribution’s package manager.
Install MySQL for “all users”, but not “as a service”. Do not install MySQL to run automatically when the computer is started, as you do not need it to do so and it will take up system resources. Make sure to note the directory in which MySQL is installed. You may also be asked to choose a password; make sure to remember it.
You will now need to set up MySQL. Note: if you are using Linux you may need to refer to your Linux distribution’s documentation on how to set it up and run it in order to integrate correctly.
Setup Process
-
Open a Command Prompt or Terminal.
-
Add MySQL to your PATH by entering:
- Windows:
set PATH=%PATH%;"C:\Program Files\MySQL\MySQL Server 8.0\bin" - MacOS:
export PATH=$PATH:/usr/local/mysql/bin
- Windows:
If you installed MySQL in a different directory, change the directory in the command as appropriate.
-
CD to a suitable work directory (your
Documentsdirectory will do) and create an empty folder for MySQL data:md mysqldataunder Windows ormkdir mysqldataunder MacOS. -
CD into the folder you just created.
-
Run
mysqld --datadir=. --initialize --consoleto set up a MySQL data store in that directory. You will be given a “Temporary password” - remember or copy it from the command line. -
Start the server:
mysqld --datadir=. --standalone --console. This will appear to freeze, but that’s OK; the server is running. -
Start another command prompt, and repeat step 2 to ensure the MySQL utilities directory is on your path.
-
Since the default password was probably a random sequence of characters, Run
mysqladmin -u root -p password xyz, replacingxyzwith what you would like the password to be. When prompted, enter the default password you were given when you initialized the data store in step 5. -
Create a database:
mysqladmin -u root -p create practical7. Give the password you set in step 8.practical7is the name of the database which you can change if you want to. -
It is ensure to do all work on a database using an admin user. Enter the MySQL interface as an admin by entering
mysql -u root -pand typing the password from step 8. -
Enter the following commands to create a user specific to the database you just created:
create user 'practical7'@'localhost' identified by 'rubbish';use practical7;grant all privileges on *.* to 'practical7'@'localhost';flush privileges;You can change the name of the user by changing practical7 where it appears as part of practical7@localhost (the name after use must match the name of the database you created in step 9). You can change the new user’s password by changing rubbish.
- Type
quitto leave the MySQL console as admin.
From now on, to get to the MySQL console you will only need to perform steps 2, 4 and 6. If you decide to create a new database (for example, for your coursework) you will need to repeat steps 6 and 9-11. Do not repeat step 5 as this will wipe out everything in the database
(although MySQL will not normally allow you to do this if there is already data in the data directory)
Important: When you are finished using MySQL you must shut it down by running
mysqladmin -u root -p shutdown and entering your admin password (from step 8).
Working with the database
-
Start the MySQL interface as your new user by entering
mysql -u practical7 -pand entering the user password you set up in step 11 above (which will berubbishif you used the command as written). -
Select the database that you created during setup:
use practical7; -
Type the following command to create a table
wd_person. You may type the command on multiple lines if it is more comfortable. Pressing return will not end the current command if you have not typed a semicolon.
create table wd_person (personID int auto_increment primary key, name varchar(30) not null, dogID int);- Type the following command to add an example entry to the
wd_persontable:
insert into wd_person (personID, name, dogID) values (null, "Robin Goodfellow", 1);- To view the added entry, type
select * from wd_person;. Note that the number 1 was automatically inserted intopersonID, even though you specifiednullin theinsertcommand, because the column was setauto_incrementwhen you created the table.
Note: using select * from... is OK for debugging and interaction, but is a bad idea when writing Python code, because it means your code does not know what order and how many fields are returned.
-
Add another person to the
wd_persontable with the name “Matilda Whirligig” anddogIDof 2. LeavepersonIDas null so thatauto_incrementupdates it for you. Aher adding them, runselect * from wd_person;again to confirm that the addition worked. -
The MySQL command to change a value in an existing row is
update. Enterupdate wd_person set dogID=3 where personID=2;. Then view the table again and check that thedogIDof Matilda Whirligig is now 3.
Note: the where clause of the update command can specify several records if you wish, but this will cause the same update to be made to all of them. Thus, update wd_person set dogID=3 where name="Matilda Whirligig"; is perfectly legal, but risks setting invalid data if more than one person in the database has that name. Usually, it should refer to a table’s primary key to ensure that only the correct record is updated.
-
Using
update, change Robin Goodfellow’sdogIDto 4. -
Create a new table
wd_dogwith the following data dictionary:
| Column Name | Type |
|---|---|
| dogID | Auto incremented 32-bit int, primary key |
| name | Variable character length string, up to 40 characters, not null |
| age | Unsigned 8 bit int |
-
Insert an entry into the
wd_dogtable by enteringinsert into wd_dog (dogID, name, age) values (3, "Toto", 2); -
We can now use the
dogIDfield to relatewd_personrows towd_dogrules. Enter the following to see how this works:
select wd_person.name, wd_dog.name from wd_person inner join wd_dog on wd_person.dogID = wd_dog.dogID;-
Create another
selectquery usinginner jointhat displays the name of a person and the age of their dog. -
Note that Robin Goodfellow does not appear in the list, because he has no related
wd_dogrow; hisdogIDentry is 4, but there is no corresponding row inwd_dogwithdogID4. Theinner joincommand specifies that only rows where records exist on both sides should be included in the result. Try retyping the command from question 11, but replace the wordsinner joinwithleft join, which specifies that all records on the left hand side of the command should be included. See how the results differ. (Note that in real databases,left joinis slow, and so should not be used if you can help it.) -
Type
insert into wd_dog (dogID, name, age) values (4, "Prince", 1);. Rerun the same command from step 11 (withinner joinincluded) and notice that Robin now does appear, because we just created a matchingwd_dogrow for him. -
You can delete a record from a table with the
deletecommand. It works the same as theupdatecommand; you specify which record to delete with thewherekeyword. You can specify multiple records if you wish, but they will all be deleted. Enterdelete from wd_dog where name="Toto";. Then try steps 11 and 13 again and notice how the results change. -
Type
quitto leave themysqltool. -
Copy and paste the following Python code into a
.pyfile, changing theconnectline appropriately:
import mysql.connectorcnx = mysql.connector.connect(user='practical7', password='rubbish', host='127.0.0.1', database='practical7')cursor = cnx.cursor()query = "select name from wd_dog where dogID=%s;"cursor.execute(query, (4,))for name in cursor: print(name)cnx.close()- Run this Python program (this is not a web-based program, so you can run it from your IDE). It should output the name of the
wd_dogwithdogID4, ie,Prince.
(If you get an error that mysql is not found as a module, run pip3 install mysql- connector-python at a command prompt, after placing Python on your path.)
- Modify the program so that it instead inputs the name of a person, and looks up their ID in the database.
In order to reduce load on the server, the MySQL cursor does not actually search for all the records matching your query at once. Instead, it searches one by one as they are needed by the for loop. That means that you cannot simply ask the cursor how many records were found (or even if any were found) because it does not know until the loop is finished. In order to give the user an error message if no record is found, you must use a flag to detect if the loop body executed or not.
-
At your command prompt, go to a working directory (not the MySQL data directory) and run:
mysqldump -u practical7 -p practical7 > p7dump.sql. Enter the password you have used for thepractical7user. This will not produce any output but will write a filep7dump.sqlcontaining the database specification and all data. This is how you will submit the database for your coursework. -
Starting from the basic to-do list application from last week (you can re-download the
zipfile if you wish), modify the to-do list application so that it stores the todoes in a database rather than a cookie. You may assume that all to-dos are shared by all users of the application, so there is no need to associate to-dos with users or implemented logging in. You will need to do the following:- Use
mysqlagain to create a table of todos. It only needs two columns: an ID and the text of the todo. The ID should be the primary key and auto-incrementing. - Write a function in the Python program that connects to the database and runs a
selectquery that fetches the todo IDs and the todo texts. The function should use aforloop through the cursor to fetch all of the values and build them into a list, as pairs. - Modify the
todos.htmltemplate so that instead of looping through a list of text todos, it loops through a list of pairs, displaying the text inside thetdelement and using the ID number (rather than the loop index) in the name of the checkbox. - Modify the Python program so that where ever the
todos.htmltemplate is used, instead of usingsession["todoes"]as the parameter, your program calls the function you previously wrote to fetch the results from the database. At this point you should be able to test this by adding some sample todos to the database with themysqlinterface first. - Modify the
/addroute so that it forms and runs anINSERT INTO...query using thenewTasktext from the form. Leave the ID column of the inserted values asnullso that auto-increment fills it in for you. - Modify the
/completeroute so that it runs a series ofDELETE FROM...queries based on thecomplete_boxes that were checked on the form. You do not need to worry about searching for the tasks, or deleting them in reverse order, as the SQL server will manage those for you.
- Use
Remember to shut down your MySQL server (mysqladmin -u root -p shutdown) when you’re finished!
支持与分享
如果这篇文章对你有帮助,欢迎分享给更多人或赞助支持!