When you say "logic" in your database, that usually means views/triggers/functions. I don't see why you can not version them, keep them in git and treat as any other code. Yes there are edge cases where there are some interdependencies, or that it's harder to "replace" functions when the signature changes, but if you are just a bit careful, and try to keep your views/functions (logic) a bit separate from tables (state), then in most cases you can just replace them, sort fo like copying a new version of a file.
I would say that the tooling is lacking in this area but there is no big underlying obstacle that would prevent you from working with code in the database the same as with code in other envs. For PostgreSQL in particular, a combination of Sqitch and Apgdiff works quite nicely. I've combined them for a particular project structure (https://github.com/subzerocloud/subzero-cli) but this approach can be generalised. I have all my database code (including table definitions) in separate files/folders, split however i want (modules), work on them in any oder i need, when the time comes to deploy, apgdiff does the diffing between live and dev versions of the database, creates the new migrations DDLs automatically, and than those migration files are managed by sqitch and deployed.