So we have a set o database changelogs and we want to achieve that whenever developer make a change in *hbm file, he run a diff comparing changelog commited to our codebase against edited hbm schema - so we can get new changelog with his recent modifications.
Liquibase-hibernate allows to compare hbm schema agaisnt any database, but is there a way to compare hbm schema against changelog xml file ?
No, it is not currently possible. Comparing a database (or hibernate mapping) to a changelog is a is a popular request, but it hasn't been implemented yet. The biggest problem is that to solve it for the general case we need an SQL parser in order to handle and blocks.
It can be done for a subset of all change logs where just standard etc. tags are used, but it has not been implemented yet, unfortunately.
Related
I think that XML files are more clear to read, but does it have advantage over SQL format. I found some info [here] (http://forum.liquibase.org/topic/liquibase-sql-vs-xml-command-changesets), but I would nice to hear others voices.
I prefer using xml file because it's more abstract. For example you can define column type by VARCHAR/java.sql.Types.VARCHAR and liquibase will replace that by default configuration for target database - so it is not database specific. But if you have some database specifics (like plsql) then I'm using .sql files and loading them with sqlFile change.
One of the primary reasons that Datical chose Liquibase as the core of our product was that the XML gave us the ability to look at the changelog in a programmatic way, allowing us to do things like forecasting the changes that would be made before they are applied to a database, and the ability to write rules against the changelog. If used with care, XML can give you a database-independent way of managing db changes also.
With the load data option that Liquibase provides, one can specify seed data in a CSV format. Is there a way I can provide say, a JSON or XML file with data that Liquibase would understand?
The use case is we are trying to put in some sample data which is hierarchical. E.g. Category - Subcategory relation which would require putting in parent id for all related categories. If there is a way to avoid including the ids in the seed data via say, JSON.
{
"MainCat1": ["SubCat11", "SubCat12"],
"MainCat2": ["SubCat21", "SubCat22"]
}
Very likely to have this as not supported (couldn't make Google help me) but is there a way to write a plugin or something that does this? Pointer to a guide (if any) would help.
NOTE: This is not about specifying the change log in that format.
This not currently supported and supporting it robustly would be pretty difficult. The main difficultly lies in the fact that Liquibase is designed to be database-platform agnostic, combined with the design goal of being able to generate the SQL required to do an operation without actually doing the operation live.
Inserting data like you want without knowing the keys and just generating SQL that could be run later is going to be very difficult, perhaps even impossible. I would suggest approaching Nathan, who is the main developer for Liquibase, more directly. The best way to do that might be through the JIRA bug database for Liquibase.
If you want to have a crack at implementing it, you could start by looking at the code for the LoadDataChange class (source in Github), which is where the CSV support currently lives.
Is it possible to generate a schema of a database from nHibernate, where I have provided nHibernate with the configuration to the database but I have not written any mappings.
I wish to get the Database MetaData/Schema programmatically.
I am using an Oracle Database. I have tried two approaches:
Approach one:
public DatabaseMetadata GetMetadata(DbConnection connectionIn)
{
return new DatabaseMetadata(connectionIn, _dialect);
}
Problem: This seems to be what I need however, although it correctly connects, it hasn't picked up any of my tables. All I provided was the nHibernate Configuration object which was populated with the contents of my nHibernate.xml.config file (connection string, driver client, etc).
Question: Why would it not return the table data? It's connected correctly but finds nothing!
Approach two:
public void DatabaseSchema()
{
var schema = new SchemaExport(nHibernateConfiguration);
schema.SetOutputFile("schema.dll");
schema.Create(true, true);
}
nHibernateConfiguration is an instance (property on class) of the nHibernate Configuration object, populated with contents from the nHibernate.xml.config class.
Problem: This simply doesn't work. Crashes with the following exception:
NHibernate.MappingException : Dialect
does not support identity key
generation
I suspect this will only generate a schema based on mappings you have created? I have created no mappings. The idea is this will work against whichever database I have connected to a generate a schema for it.
Question: Is my belief that this method will only generate a Schema based on my mappings? If not, Am I using it correctly?
Hopefully this is clear enough, comment if I need to provide more info.
Thanks In Advance.
To be clear: I have a database and want to get meta data representing the database, a schema.
NHibernate is actually based on the mapping files. You could generate classes or tables from them. There are tools to generate the mapping files, but they are based on the classes, not the tables.
Answers to your specific questions:
Approach one: NHibernate does not read table definitions from the database. All the table definitions need to be specified in the mapping files.
Approach two: SchemaExport creates an SQL file (Create tables, indexes etc) from the mapping definitions. It is actually recommended to use it, unless you need to cope with legacy databases. The output file should be called *.sql, not *.dll.
The error you get is most probably because you try to create an identity id on an oracle database (or another which does not support identity columns). Use hilo instead (or, if you don't like it, guid.comb or native). I just wonder why you get this error, I thought that you didn't write any mapping files?
Conclusion:
I don't know of any tool which create NHibernate mapping files from database tables. There may be one, most probably it is not free or not mature (because otherwise it would be well known). So I suggest to think about generating the table definitions instead, or, in case you have a legacy database, you need to go through writing the mapping files manually.
There are several tools to help you out but the two I use the most are the following two.
NHibernate Schema Tool
NHibernate Mapping Generator
If you already have a schema you can use the NHibernate Mapping Generator to create your mappings. You can then use the mappings for whatever you want. Modify them and use NHibernate Schema Tool to manage the actual schema.
If you don't have any schema and that is what you are trying to create you are on the right track. First you need to "map" your classes. Preferably using Fluent NHibernate or ConfORM like Michael Maddox suggested.
I don't know the purpose of this. If it is database schema management I would recommend against using NHibernate. NHibernate was never developed as a schema manager tool so it probably should not be used this way. Admittedly I might have misunderstood you somehow and this answer could be completely wrong.
I may be interpreting the question wrong, it's not really clear what you are asking for.
Assuming you have created classes and configured NHibernate correctly and you want to create tables in the database for those classes, you have at least two potential ways to try to generate a database without creating NHibernate mappings, both of which will likely work much better with at least some hints about how to do the mappings:
Fluent NHibernate Automapper
ConfORM
There is a decent learning curve for both options.
Another option is to try one of the commercial visual designers for NHibernate, although those tools aren't quite mature enough to do this really well in my experience.
Core NHibernate is not designed or intended to create tables without mappings files.
I'm evaluating liquibase for a project starting today.
Has anybody used it to create procedures, functions, basically all of the plsql stuff?
If not, is it possible to write embedded sql code in the xml files?
There is a built-in createProcedure tag in liquibase for managing procedures. The best approach is usually to combine the or tags with runOnChange so liquibase will update your procedure when and only when you update the definition. That way you can do diffs between your changelog xml files over time and see how the procedure has changed.
Using the sqlFile tag to reference file per stored-proc is also popular, or, like you said, you can use the sql tag to inline custom sql.
I've encountered issues with trying the use the sql tag for stored procedures, triggers, and functions, but in my case these were provably issues with the MySQL JDBC driver, and not Liquibase itself. The practice I've settled into is to use the sqlFile refactoring as Nathan suggests, then to control the SP/trigger/function code in the same project as the changelog, versioned in the source code system along with it. This lets you manage the SP/whatever code just like it was real source code.
Setting runOnChange="true" in the changeSet containing the sqlFile refactoring is essential. It is this switch (thank you, Nathan) that enables real source control of procedural database code.
While I haven't used liquibase for stored procedures, I have some experience of Liquibase for more generic operations.
It is possible to write custom sql, either embedded in the xml file or referenced from an external file.
I'm using NHibernate 2 and PostgreSQL in my project. SchemaExport class does a great job generating DDL scheme for database, but it's great until the first application.
Is there any way to generate "migration" DLL (batch of "ALTER TABLE"'s instead of DROP/CREATE pair) using NHibernate mapping files?
Look into SchemaUpdate. Very similiar API as SchemaExport but it only creates migrations.
While SchemaUpdate very much answers my needs, it still has several problems. For example it refuses to put a new restriction on existing database column even if it's not gonna conflict with existing data.
I'm going froward to extend SchemaUpdate a little bit or, if fail, switch to one of that hand driven migration tools (for example Rails one).