I have created a table as below:
+------------------+--------------+------+-----+------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+------------+----------------+
| category | varchar(20) | NO | | NULL | |
| report_id | int(5) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | NO | UNI | NULL | |
| URL | varchar(200) | NO | | NULL | |
| refresh_type | varchar(30) | NO | | On Request | |
| create_dt | date | NO | | 9999-01-01 | |
| modified_dt | date | NO | | 9999-01-01 | |
| project_type | varchar(60) | YES | | NULL | |
| project_name | varchar(60) | YES | | NULL | |
| project_location | varchar(255) | YES | | NULL | |
+------------------+--------------+------+-----+------------+----------------+
I have inserted records into this as well. I am trying to automate the process of inserting and maintaining and I am getting only few columns like category, name and URL from a data feed.
According to the process, a user can update the records and change the other fields to make them useful, and the next time when I try to insert records, I want to perform upsert based on name. I am performing the process using python. here are the steps I tried:
dash= df.loc[:,['folder','name','url','url']].values.tolist()
dash_insert_sql= ("""insert into dashboards (category
,name
,URL
) values (%s,%s,%s)
on duplicate key update URL = values(%s) """)
cur.executemany(dash_insert_sql, dash)
When I try this, I am getting
Traceback (most recent call last):
File "C:\Python\Mysql\report_uri.py", line 65, in <module>
cur.executemany(dash_insert_sql, dash)
File "C:\Python\lib\site-packages\MySQLdb\cursors.py", line 228, in executemany
q_prefix = m.group(1) % ()
TypeError: not enough arguments for format string
Here is the example data:
My input is a list of lists.
[['Student Information', 'Active Students not Scheduled', 'https://example.com/SASReportViewer/?reportUri=/reports/reports/af4f7325-860f-4958-ad83-bb900f726b32&page=vi6', 'https://example.com/SASReportViewer/?reportUri=/reports/reports/af4f7325-860f-4958-ad83-bb900f726b32&page=vi6'], ['Student Information', 'Admissions Statistical Comparison from Snapshots', 'https://example.com/SASReportViewer/?reportUri=/reports/reports/6150909f-3ab4-4ec7-8ef0-7efdb1f09300&page=vi6', 'https://example.com/SASReportViewer/?reportUri=/reports/reports/6150909f-3ab4-4ec7-8ef0-7efdb1f09300&page=vi6']]
Please let me know how to proceed or where I am going wrong. Thank you.
dash= df.loc[:,['folder','name','url']].values.tolist()
dash_insert_sql= ("""insert into dashboards (category
,name
,URL
) values (%s,%s,%s)
on duplicate key update URL = values(URL) """)
I tested it by changing the url of a report with that of another one and it did update the url and no new rows were added.
Related
I am doing a side project to help me learn SQL.
I have setup 2 different tables:
computers
+------------------+-----------+------+-----+---------+-------+
│| Field | Type | Null | Key | Default | Extra |
│+------------------+-----------+------+-----+---------+-------+
│| serial_number | char(25) | NO | PRI | NULL | |
│| operating_system | char(10) | YES | | NULL | |
│| purchase_year | int(4) | YES | | NULL | |
│| assigned_to | char(100) | YES | | NULL | |
│+------------------+-----------+------+-----+---------+-------+
employees
│+------------+-----------+------+-----+---------+-------+
│| Field | Type | Null | Key | Default | Extra |
│+------------+-----------+------+-----+---------+-------+
│| email | char(100) | NO | PRI | NULL | |
│| first_name | char(25) | NO | | NULL | |
│| last_name | char(25) | NO | | NULL | |
│| office | char(5) | NO | | NULL | |
│| assigned | char(25) | YES | | NULL | |
│+------------+-----------+------+-----+---------+-------+
These both have a few entries while I am testing, but in trying to write a search function based off the employee email, I am reaching a snag with SQL queries. I'm pouring through the documentation, but not understanding it well, and can't find a good example of what I am trying to do to follow along with.
Here is what I am attempting to do with the query:
I want to grab a the employee row matching email address provided, and if the "employees.assigned" field is set (not null, think EXIST is used?) then I want to also grab the "computers.serial_number" row matching that column value
I can do what I want with 2 separate queries, but I want to see if it is possible with only one to clean up code and make the query as fast as possible. Any further documentation you think is worthwhile for this project is very welcome as well!
For those people finding this on google:
What I found worked for my need:
SELECT * FROM employees LEFT JOIN computers ON employees.assigned=computers.serial_number WHERE email='email#example.com';
Here's my table.
+-------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+--------------+------+-----+---------+----------------+
| ID | int(11) | NO | PRI | NULL | auto_increment |
| Postcode | varchar(255) | YES | | NULL | |
| Town | varchar(255) | YES | | NULL | |
| Region | varchar(255) | YES | | NULL | |
| Company Name | varchar(255) | YES | | NULL | |
| Fee | double | YES | | NULL | |
| Company Benefits | varchar(255) | YES | | NULL | |
| Date Updated | date | YES | | NULL | |
| Website | mediumtext | YES | | NULL | |
| Updated By | varchar(255) | YES | | NULL | |
| Notes | varchar(255) | YES | | NULL | |
| LNG | varchar(255) | YES | | NULL | |
| LAT | varchar(255) | YES | | NULL | |
+-------------------+--------------+------+-----+---------+----------------+
You can see we have an "Updated by" column.
How can I make it so that, when a user updates the row, the "Updated By" column automatically updates (or inserts if it's a new row they're adding) with the currently logged-in users name?
Many Thanks
You will have to explicitly make sure about that and whenever an UPDATE is happening then you need to update that column as well saying below. Best way to assure it, have your application logic fill in the column whenever an UPDATE to the record is happening from current logged-in user principle or claim
update tbl1
set ...,
Updated By = <logged in user name>
where Id = <some val>
You can use USER() or CURRENT_USER() in Update or Insert statements to achieve needed effect.
From my side - the only one secure way is to create stored procedures, providing inserts or updates to desired table.
Indeed, this problem was discussed here:
mysql Set default value of a column as the current logged in user
Something like this !
CREATE TRIGGER `updater`.`tableName_BEFORE_INSERT` BEFORE INSERT ON `tableName`
FOR EACH ROW
BEGIN
Set New.Updated_By = current_user();
END
I have a webapp that I'm building. This webapp will take as input some products (cars, motos, boats, houses, etc...) and each product will have one or more photos associated with it. The id of each of photo is generated by the uniqid() function of php.
My problem is:I can't seem to fit more than two id_photos into the same column
+-----------+------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------------------------------+------+-----+---------+----------------+
| carid | int(11) | NO | MUL | NULL | auto_increment |
| brand | enum('Alfa Romeo','Aston Martin','Audi') | NO | | NULL | |
| color | varchar(20) | NO | | NULL | |
| type | enum('gasoline','diesel','eletric') | YES | | NULL | |
| price | mediumint(8) unsigned | YES | | NULL | |
| mileage | mediumint(8) unsigned | YES | | NULL | |
| model | text | YES | | NULL | |
| year | year(4) | YES | | NULL | |
| id_photos | varchar(30) | YES | | NULL | |
+-----------+------------------------------------------+------+-----+---------+----------------+
What I would like to happen is something like this: INSERT INTO cars(id_photos) values ('id_1st_photo', 'id_2nd_photo')
Ending up having something like this:
| 60 | Audi | Yellow | diesel | 252352 | 1234112 | R8 | 1990 | id_1st_photo id_2nd_photo |
Eventually I would have to grab those photos from the folders they are in which is something like this: /var/www/website/$login/photos/id_of_photo with the query select id_photos from cars where carid=$id.
You may found some data types that is not proprelly good for the data that the server will receive but I'm one week into mysql and I'll worry about data types later on.
First of all I don't know if that is possible, if it's not how can I design something to work like that?
I have found this question that is quite the same of mine but I can't seem to implement something like this: add multiple values in one column
You can insert the concatenated values into a field. But it is not a good practice. You can create another table with foreign key having the id of the parent table.
You can easily adapt the approach in the linked question and even remove one table needed:
You first table stays almost the same, but has the id_photos column removed:
+-----------+------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------------------------------+------+-----+---------+----------------+
| carid | int(11) | NO | MUL | NULL | auto_increment |
| brand | enum('Alfa Romeo','Aston Martin','Audi') | NO | | NULL | |
| color | varchar(20) | NO | | NULL | |
| type | enum('gasoline','diesel','eletric') | YES | | NULL | |
| price | mediumint(8) unsigned | YES | | NULL | |
| mileage | mediumint(8) unsigned | YES | | NULL | |
| model | text | YES | | NULL | |
| year | year(4) | YES | | NULL | |
+-----------+------------------------------------------+------+-----+---------+----------------+
Then you'll add a second table to store the links to the photo ids:
+-----------+------------------------------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------------------------------+------+-----+---------+----------------+
| carid | int(11) | NO | MUL | NULL | |
| id_photos | varchar(30) | NO | | NULL | |
+-----------+------------------------------------------+------+-----+---------+----------------+
Both tables are linked by the field carid (You should even make carid in the second table a foreign key pointing to the one in the first table).
Each id_photos then results in a new row in the second table.
To query the data you probably need a JOIN between both tables and maybe a GROUP BY to reduce the result to one row per carid again, but this depends on the other usecases.
You can insert the string formatted woth multiple photo name
INSERT INTO cars(id_photos) values ('id_1st_photo, id_2nd_photo')
In this way you don'have a well normalized database structure so you have problem when retrive the singole foto name ..
i suggest you of normalize the id_photo column in a separata table with reference to the master table and in this way store each single photo in one row
I'm setting this up in phpmyadmin. It's a simple table listing a collection of films. One column records the year the film was made. Another the decade it was made. A third, the genre.
I'm getting this message from phpmyadmin:
1062 - Duplicate entry '30' for key 'decade'
This is on the second insert. But, this will also happen for genre and eventually for year.
I thought at first that making these fields varchar instead of int would solve the problem, but I guess I just don't have the colums set up correctly.
What do I need to do?
My Schema:
MariaDB [movies]> desc films;
+------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| alpha-name | varchar(50) | NO | UNI | NULL | |
| page-link | varchar(100) | NO | UNI | NULL | |
| sm-pic | varchar(100) | NO | UNI | NULL | |
| year | varchar(4) | NO | UNI | NULL | |
| decade | varchar(2) | NO | UNI | NULL | |
| genre | varchar(10) | NO | UNI | NULL | |
+------------+--------------+------+-----+---------+-------+
I see now that the keys are designated UNI, but where in phpmyadmin do I select it so that I can allow duplicates?
I can't see where I can thank people so I'm doing it here...
dropping the indexes on these fields does seem to have worked. Thanks for the specific code.
try:
Alter films drop index <column_name>
I'm trying to import a CSV file into a MySQL table and I'm having all kinds of trouble getting it to work. Here's what I'm trying to do:
I am working on a video database and have an existing table with data already in it called episodes. Here's how it's set up:
+--------------+-----------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-----------------------+------+-----+-------------------+-----------------------------+
| title | varchar(40) | NO | MUL | NULL | |
| media_id | varchar(11) | NO | | NULL | |
| ep_info | varchar(75) | YES | | NULL | |
| air_date | varchar(20) | NO | | NULL | |
| trt | varchar(8) | NO | | NULL | |
| times_played | mediumint(9) unsigned | NO | | 0 | |
| last_played | timestamp | YES | | NULL | |
| entered | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| ep_desc | varchar(300) | NO | | NULL | |
+--------------+-----------------------+------+-----+-------------------+-----------------------------+
The primary key is the id field, with the title field set as a foreign key to the shows table. The shows table looks like this:
+-------------+-------------+------+-----+------------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+------------+-------+
| title | varchar(50) | NO | PRI | NULL | |
| title_image | varchar(50) | NO | | NULL | |
| gif_image | varchar(50) | NO | | NULL | |
| info_url | varchar(30) | NO | | shows.html | |
+-------------+-------------+------+-----+------------+-------+
My CSV file is in the following format:
"Big Wolf On Campus","BWOC0102","Season 1 Episode 2: The Bookmobile","April 9, 1999";"21:57",NULL,NULL,NULL,NULL,"Once every 70 years, a window of transference opens that offers Tommy a chance to pass his curse to another person. Merton volunteers but that same day a bookmobile shows up in Pleasantville and people start disappearing."
"Big Wolf On Campus","BWOC0103","Season 1 Episode 3: Butch Comes To Shove","April 16, 1999","21:06",NULL,NULL,NULL,NULL,"When a character from a 1950s educational film gets sick of the rules he decides to leave the movie for Pleasantville. While there Butch decides to find someone to bring back to his black-and-white world - and Stacey is at the top of his list."
During the import, I want the data in the CSV added to the existing data in the table. I also want the last_played field set to NULL (only updated when the show plays), the entered field set with a current timestamp, and the id field auto_incremented with the next value for the table.
Here is my import statement:
LOAD DATA INFILE 'ytv.csv' INTO TABLE episodes
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n';
The resulting error message:
ERROR 1406 (22001): Data too long for column 'air_date' at row 1
What am I doing wrong here? It seems like the data is getting shifted over one column when it's importing (such that ep_info from the CSV is going into the air_date column) but I can't figure out why. Any insight would be much appreciated for this MySQL novice.
It seems you have some new episodes with no mapping entry in shows table. You can create a new table like episodes, remove any constraints, load the data to the new table, insert all missing show titles to your show table, then insert episodes from the new table to the episodes table.
Or you can delete the foreign key, load the data, amend you shows table, then add the foreign key back.