Changing WordPress Settings Directly

A recent update of PHP broke one of my oldest WordPress blogs. It was set up with an offset for the timezone, which is no longer supported. What it looked like was the white screen of death, but enabling debug mode in my wp-config.php gave me some hints.

The first hint that it was something weird is that all of my other blogs, which all run off of the same database, were all fine. I can look at their settings, log into their administration interfaces, change their settings, but my old blog would not load.

After considerable DuckDuckGo-ing, I figured out the setting that needed to be fixed, but because I couldn’t load the administration interface, I could not fix the setting. Access to all of your WordPress settings is inside the database, so I had to figure out how to change that setting directly in the database, preferably without ruining everything.

The option was timezone_string, but if you don’t know how the database is laid out, you have to do some poking before you can get yourself sorted.

All of the options are in a table called options, or in my case, since I have multiple WordPress blogs in the same database, there is a prefix underscore first. I found this by logging into the database engine, navigating to the correct database, and then using the show tables; command.

show tables;
show columns from $BLOGNAME_options;

The next wrinkle was interpreting the results – they lay out the columns vertically, which isn’t very intuitive, since we definitely asked for columns, and they are shown as rows. Still, it is standard, and looks like this:

option_idbigint(20) unsignedNOPRINULLauto_increment

I was then able to figure out that I need to change the option_value for the row with the option_name timezone_string. Since I want to figure out what to change it to, I tried this:

select option_value from $BLOGNAME_options where option_name='timezone_string';

That showed me the problem that I was seeing in the debug messages. Then I looked at the timezone_string from one of the blogs that wasn’t broken, which in that case was “America/Toronto”. Then I finally had enough information to update the option_value to (hopefully) fix my ailing blog. So, I ran this:

update $BLOGNAME_options set option_value = 'America/Toronto' where option_name = 'timezone_string';

And it worked! It took too long, and was stressful and annoying, and made me wish that all of these options were in a flatfile, ’cause doing this with no interface is annoying, and completely beyond the average blog-haver, I think.

If the whole blog is going to go down from a borked option, maybe the blog should load a default set of options and then tell the user which options to fix.

Using the Tilde as a Boolean NOT in Pandas

There are lots of times when you want to get the inverse of an operation – like finding all of the rows not like some criteria. This is possible, but hard to search for, especially because this functionality is hiding behind the “tilde (~)” operator.

Here’s how it works:

import pandas

What if you have a column that is supposed to be a date-as-a-number, but your parse-this-column-as-a-date code keeps barfing? Now you can filter by a doesn’t-match-this-format criteria.

myDataFrame = pandas.DataFrame([("20010901"),("18670701"),("10660106"),("20010901"),("Thursday")], columns=["A"], index=[1,2,3,4,5])

Return a dataframe where this format doesn’t match

weirdos = myDataFrame[~(myDataFrame['A'].str.match('\d\d\d\d\d\d\d\d'))]

weirdos is now a DataFrame which includes the rows where it doesn’t match the format, because of the tilde (~) beginning the definition.

I have also used this is get subsets of non-conforming DataFrames – I know what it is supposed to be like, but it is too hard to know all of the ways that your data may not be like that.

I found this when I was looking for the NOT equivalent of .isin – which unfortunately doesn’t exist. That’s the problem with Huffman coding your operators into single characters – you can’t easily search for them if you don’t know what they’re called.


One of the delights of coming back to Python in an intensive way after many years is some of the new ways to do the usual things that I hadn’t learned before.

In this case, I am finding the use of “f-strings” (introduced in Python 3.6, described in PEP 498) to be quite delightful.

print(f"Warning: {sys.argv[2]} exists!")

The previous syntax for format strings always slipped away from my memory, but these seem a lot stickier, and they give me a lot of freedom to just keep writing.

Python is not the greatest language in the universe, but it can allow a lot of fluency that I never experienced in other languages.