This article is a cheat sheet to inspect what's going on with the imported data by Xperience by Kentico Migration Toolkit, resolve some CI/CD issues and on many other occasions!
Below are just links to the SQL code snippets, make sure to pin and make use of them!
It's been over a year since Kentico delivered a massive content structure modernization Refresh. The underlying database schema underwent significant changes to support the rapid growth of the Xperience by Kentico product.
In their daily tasks, developers don't usually need to remember the structure of the database tables and how they relate to each other. Kentico provides robust and flexible APIs that make it easy to query the data they need: Content Hub items, Web Pages, Objects, and Database Tables. But what if you execute the query, and the data returned is not what you expect? And why may this happen?
Occasionally, I find myself writing the same SQL queries to check what is stored in the database vs what I see (or don't see?) on the screen. Kentico provides a great documentation article explaining what information is stored in which database table.
This article is just a cheat sheet for those of you, who are about to:
Let's start with easy things, this is basic information about the content hub item - a coffee product "El Salvador Finca San Jose" from the Dancing Goat website:
Here is the summary of the tables we need to join:
Notice that I'm using LEFT joins here, and it's for a reason. This will help you identify missing or orphaned records if there were any. Missing or orphaned records may appear in your database due to incomplete data migration or CI/CD restore with some files missing.
Moving on, let's add our custom content type fields to the query:
Each custom content type has a dedicated SQL table to store custom field data, usually named <namespace>_<customTypeName>. We need to join it with the following condition: ContentItemDataCommonDataID foreign key, and filter out our specific content type 'DancingGoat.Coffee':
You will immediately notice that our last query returns fewer fields than you can see in the user interface. This is because the Coffee content type has some of its fields inherited from Product fields reusable field schema:
These fields need to be queried from CMS_ContentItemCommonData table we joined earlier:
The next thing you will notice is how Xperience by Kentico stores references to images (or any other assets) stored in Content Hub. Documentation guides recommend storing images in the Content Hub, and Dancing Goat follows this guide.
The previous query will return the following result for the ProductFieldsImage field:
[{"Identifier":"279bb55f-81e3-4d93-9cff-8372dc34cdc5"}]
That is a unique identifier of our image - yet another item from the Content Hub of DancingGoat.Image type, and with the query below we can get some useful metadata information, and can even locate this asset on disk when we need to inspect the binary:
Other fields from the previous queries where you will find unique identifiers are CoffeeProcessing and CoffeeTastes, these are Taxonomy fields, and they store a list of TagGUID records from CMS_Tag table:
This way we can join this data if needed:
And finally, web pages from the Web channel. In Xperience by Kentico every web page is a little bit of content item đ
We just need to join a couple more tables:
The queries above are beneficial while debugging data issues. But what if you need to check what SQL queries Xperience generates when you call query APIs? In this case, integration with MiniProfiler would be very helpful! Check out this nuget package by Sean G. Wright. I think this is one of the must-have packages you should install for every project!
Don't be afraid of making your hands dirty again by writing some SQL queries to identify data issues within your Xperience by Kentico solution. Hopefully, these little code snippets together with Kentico's detailed documentation will give you some good boosting when you start investigating things!
It's easy to start working with us. Just fill the brief or call us.