how to insert an article into a wordpress database using mysql

there are a million reasons why you might want to add a new wordpress article manually using mysql. for me, i wanted to migrate custom-coded photo gallery content into the main wordpress installation, so that things on the website would become more streamlined and update-able.
most articles on the net push the idea of using wordpress’ own functions to add or alter blog posts in php (and probably for a reason). but if, like me, you just want a one-time set of mysql commands, here’s a “quick and dirty” way that has worked for me in wordpress 4.9.5:

the basics
example of a quick link to a blog post using the article ID (database: wp_posts.ID):
http://www.thinkoholic.com/?p=28714

quick link to edit a post using article ID:
http://www.thinkoholic.com/wordpress/wp-admin/post.php?action=edit&post=28714 (requires login, obviously)

the very least you’ll need to do in mysql, is create your blog post in wp_posts, and then assign a category in wp_term_relationships:

how to insert an article into a wordpress database using mysql

step 1: insert your article into table wp_posts using mysql

INSERT INTO `wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_status`, `comment_status`, `ping_status`, `post_name`, `post_modified`, `post_modified_gmt`, `guid`, `post_type`, `comment_count`) VALUES ([ID], [AUTHOR], '[DATE1]', '[DATE2]', '[CONTENT]', '[TITLE]', 'publish', 'open', 'open', '[POSTNAME]', '[DATE3]', '[DATE4]', '[GUID]', 'post', 0);

details:

  • [ID] needs to be a unique number that increases for each entry. note this number as you’ll need it for step 2.
  • [AUTHOR] should be your author ID. you can find it in table wp_users.
  • [DATE1] and [DATE2] will be your post date and time, first in your timezone and second in GMT, using the format “2005-12-31 01:23:45”. these timestamps will be used to show when the article was published.
  • [CONTENT] is the main content of your blog article.
  • [TITLE], unsurprisingly, is where your blog title goes.
  • [POSTNAME] is typically a cleaned-up version of your title with only alphanumeric characters and hyphens (“−”). it can have no special characters or spaces (usually replaced with a hyphen), and it also shouldn’t have any double hyphens (“−−”).
  • [DATE3] and [DATE4] are, as far as i can tell, just shown in the backend.
  • and finally, [GUID] is an important one. it’s the complete URL (or permalink) for your article, including your domain name (e.g. “thinkoholic.com”), any folder structure (such as “/year/month/day”) and a unique article identifier. like [POSTNAME] it can’t have any special characters or double hyphens. in my script, i used a combination of my post’s name and the article ID (see example below), so i’d be sure it’s definitely unique across the entire wp_posts table. getting the GUID wrong will result in your article being unreachable, even if you link to it using just its ID (e.g. http://www.thinkoholic.com/?p=28714) – see “troubleshooting” below.

here’s an actual example from my own migration:
INSERT INTO `wp_posts` (`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_status`, `comment_status`, `ping_status`, `post_name`, `post_modified`, `post_modified_gmt`, `guid`, `post_type`, `comment_count`) VALUES (28716, 1, '2018-05-30 00:00:00', '2018-05-30 00:00:00', 'gallery test post <br/><br/><br/><a href="http://www.thinkoholic.com/?p=98">related blog post</a>', 'photo gallery: fireworks', 'publish', 'open', 'open', 'photo-gallery-fireworks-s200-en', '2018-04-24 23:59:59', '2018-04-24 23:59:59', 'http://www.thinkoholic.com/2005/01/01/photo-gallery-fireworks-s200-en-28716', 'post', 0);

step 2: assign at least one category using mysql

now it’s time to assign a category, and possibly also tags, in wp_term_relationships. the post category is NOT defined in wp_posts itself (despite there being a field ‘post_category’), but in another table, wp_term_relationships.
you’ll need the correct ID number for your category or tag. to find which number to use as “term_taxonomy_id” in the second mysql statement, find the term ID of the desired category in wp_terms, then search for this term_id in wp_term_taxonomy and note the number in term_taxonomy_id. this is your category’s real unique identifier. note that term_id and term_taxonomy_id are probably similar but different!

for each category or tag you want to assign to the post, create a separate entry in wp_term_relationships. be sure to use the article ID specified in the above command as your object_id. here’s one example each for category and tag:

assign article 28716 to a category. in my case, category “photos” = term_taxonomy_id 5:
INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`) VALUES (28716, 5);

assign article 28716 to a tag. in my case, tag “old gallery” = term_taxonomy_id 222:
INSERT INTO `wp_term_relationships` (`object_id`, `term_taxonomy_id`) VALUES (28716, 222);

troubleshooting and code clippings

URL 404 problems:
if you’ve pushed an article into your database this way, and calling the post using http://thinkoholic.com?p=xxx results in a 404 error message, the problem is most likely in your “guid” field: it defines the article’s URI, and needs to be sanitized – only alphanumeric characters (a-z, 0-9) and hyphens (“-“), no special chars, no double hyphens (“–“) allowed either!
if this concerns just a few articles and you’re happy to do it manually, just open the article in wordpress and click “update”, and the “slug”/”guid” field is automatically checked and updated.

post-fixes:
mysql command to find posts with double hyphens in the GUID:
SELECT * FROM `wp_posts` WHERE `guid` LIKE '%--%';

this one’s more a very specific note-to-self than anything else: find posts with hardcoded gallery that have html-links in image alt-texts.
SELECT * FROM `wp_posts` WHERE `post_content` REGEXP 'alt=\\".[^\\"]*\\<a.*\\"' AND `post_type` = 'post' ORDER BY `ID` DESC;

in php, a better version to do find these would be:
/(alt|title)\=.*(<a href).*?(\<\/a>)/

please let me know in the comments whether this works for you and/or if you have a better database-side way of inserting posts into wordpress!

5 thoughts on “how to insert an article into a wordpress database using mysql

  1. Hi, thanks for your useful article. I managed to make it works properly.
    How about adding post tag and featured image in advance?
    Thank you.

  2. the post tag part is right there in the article: see step 2 (for categories and tags).
    featured image was more than i needed, so i’m afraid can’t help you with that.

  3. Hello friend
    I have multiple posts that I have exported from other hosting as .sql file and I want to add that file in my new hosting phpmyadmin. On using the option import , It is creating separate database. How can I import those posts in my exisitng site . Please tell me this. So much thanks

    Regards

  4. Hi Manjeet,
    you’ll need to adapt the SQL commands in your .sql file, especially change the target database name.
    Best to look for a quick introduction to SQL somewhere on the internet. :)

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.