"Structured" use of SQL backends?

This is a good question! Ultimately, Prodigy is pretty agnostic to what you pass around in the task dictionary. There are some conventions, like the key "label" or "spans" in some built-in recipes and interfaces, but most of it is up to you. In the default database model we ship with Prodigy, we tried to make fewer assumptions about what the example data means and how to translate it to a database schema. When we built Prodigy, we didn’t want to make any decisions here that’d be very difficult to reverse and potentially lock users in and cause migration issues down the line. Instead, we focused on making the Database handler fully customisable.

If you do have more specific requirements (or opinions on how you want your database to be structured), Prodigy lets you pass in your very own Database class that can take full control over how to store and retrieve the data. It just needs to exposes the methods that Prodigy expects. (Also see this thread for more details.)