How to export the DDL of domains(Database schema) of new version for update - grails

I have developed a application with Grails earlier.Now as per new requirement there is a need to modify the existing domain classes as well as adding a new classes and changing / establishing new relationship between the as well.
Now the new requirement has been implemented and I am going to deploy to production environment. however, the DBA want a script change the production database DDL. DBA is not allowing the auto create / update of database schema while bootstrapping the application.
I know how to export DDL of for creating tables. but that script will drop tables which means all data will be lost.
But I don't know how to export DDL for DDL-update (no drop tables/recreate tables). Anybody has good suggestion ?

You can not expect the existing data to get stored according to the new database schema as is.
For example, you have a table Sample with the contactNumber field with the nullable : true constraint in your existing schema and in your new schema this constraint has been changed to nullable : true & unique : true.
In such cases database will fail to keep the existing data intact or adapt to new schema.
To preserve the existing data, you may have to go through a tedious process like -
Take backup of the existing database.
Make a note of the modification you have made to the existing Domain classes.
Find out which modifications may lead to failure / data loss.
Drop the earlier database schema & Deploy the new application and let it create the database schema.
Write a script or utility which will process & store the data from database backup according to new database schema.Make sure the utility you have written has the capalibility to handle the modification(constraint, field added, field removed) done to the database schema.

Related

Duplicate postgres schema

I'm working on multi-tenant system in which I need to work on different tenats. in some cases I need to create new schema which contains some tables and default data. for that I just want to duplicate or copy public schema with diff. name Is there any way to duplicate or copy it.
I did work around on this problem but I want a solution to copy schema not to create schema and regenrate table and data
Take a back up of the schema you want along with the data In a plain text SQL file using pgadmin. And then create new schema and execute the SQL file under the new schema.

Manually Editing an EF7 Migration Class & Snapshot

The EF7 migration add command (to date, beta5) compares the model classes defined in the DbContext against the current model snapshot, creates a new migration class, and updates the model snapshot.
I need to modify the migration to make it generate different DDL SQL. As an example, EF7 uses sequences for SQL Server auto-increment values, and I would like it to use identity. However it could be any other reason. The migration remove command would physically delete the migration files and revert the model snapshot, so it's useless in this case.
There are 3 files that contain related code that look like they need to be edited:
The primary migration class: The Up and Down methods should be modified.
The DbContextModelSnapshot file contains Annotations that need to be modified
The secondary migration partial class: The badly named [migration].Designer.cs file also contains a model snapshot for the migration. I'm assuming this snapshot needs to match the model snapshot in item 2, but am not certain. The only information I have about the purpose of it is from Brice's blog , which says "It’s there in case you or a provider need to inspect the model for additional information during a migration."
Specific questions:
Do the two model snapshots need to be kept in sync in order to correctly perform migrations?
Is modifying 3 separate files the only way to edit the migration? (Although depending on the changes, the model snapshots may not have to be touched in some cases.)
Is there some EF command that would regenerate just the model snapshots, but not the migration methods?
Specific answers:
Do the two model snapshots need to be kept in sync in order to correctly perform migrations?
No, the snapshot in the migration is a last resort for provider writers. For example, SQLite can't rename columns so it could use migration's model snapshot to do a table rebuild for this operation. 99% of the time, it won't ever be used.
Is modifying 3 separate files the only way to edit the migration?
Most of the time, you should only ever edit the main migration file. In rare cases, you may need to edit the model snapshot if you're working in a team environment and you encounter a merge conflict. You can ignore the designer file; it just captures some metadata about the migration.
You may not have to edit anything if you configure your model correctly. For example, to use identity instead of sequences, override DbContext.OnModelCreating() and add modelBuilder.ForSqlServer().UseIdentity().
Is there some EF command that would regenerate just the model snapshots, but not the migration methods?
No, it shouldn't be needed since you almost never edit these files.

EF Code First deployment

I have an MVC code-first application that creates a database based on my schema. On the production machine, we will need to first create the database (empty, with no tables), so that we can assign the proper username and password to my dbcontext in the connection string. Considering that the DB is created on production, what should my code do?
I can't use DropCreateDatabaseIfModelChanges because a DB will already be created with no Metadata.. and can't use DropCreateDatabaseAlways because I need it created only the first time.
I also tried this:
if (context.Database.Exists() && !context.Database.CompatibleWithModel(false))
context.Database.Delete();
if (context.Database.CreateIfNotExists())
but context.Database.CompatibleWithModel(false) return always TRUE on an empty database for some reason...
You might need to deploy the database schema via SQL script manually. You can generate the script from your production database instance.

Migrations with EF. Where they are stored?

Yesterday i was absolutely sertain that all migrations data for EF placed in classes, placed in my solution as nested from DbMigration. But today i was dig a slightly deeper(just try to fallback to old migration with enable data loss not with nu-get and visual studio, but with code())
DbMigrator fg = new DbMigrator(new Settings() { AutomaticDataLossEnabled = true});
fg.Update("MigrationName");
And get exception, smth like "string should be truncated", those means that migrator tried to update column from big to small MaxLength attribute. So, i had excluded migration that caused this update and move this changes to migration, those create tables. The error still was occured. I got to intellitrace and it said that those(deleted) migration still was called. Looking to requests told me things like this:
SELECT [Extent1].[MigrationId] AS [MigrationId] FROM [dbo].[__MigrationHistory] AS [Extent1]
Looking to a table __MigrationsHistory and get my deleted migration there with field model that contains crypted data(don't decrypt this yet) . I was realy shocked. Does this means that all code, have written in classes is just the fake and really executed code placed here? And does anyone know, how to work with this table, register projections of migration classes to it etc. Or the once way to work with migrations is nu-get console?
I am not fully sure what your primary question is, so I will first try to answer last part about __MigrationHistory table.
Code in classes is not fake, your code in classes is compiled and run.
This table, however, really contains your database model, but it is not encrypted, it is compressed. The reason why Migrations API needs to store your model, is to be able to compare it against your current actual model and track changes for you (for example when you add a new property it will be able to tell what property you added and to perform automatic db migration).
In previous version of EF there was an EdmMetadata table where hash of your model was stored, and EF was able to detect if you made some changes to model by comparing stored and current model hash value. New version when migrations are enabled stores entire model as compressed blob, so it can do diff between the model that was used to create database and current model you are using, and make automatic migrations accordingly.
You should not work directly with this table, it is automatically populated by migrations API, but nuget console is not the only way to do migrations, you can check this resource for some insights how to do it from code.
Now, regarding your question from question title (where they are stored?), migrations are stored in code, in a class inheriting from DbMigration class that migrations API creates for you when you do Add-Migration command in nuget console. When you perform an migration (Update-Database), either from nuget package manager console or from code, API will compare your current model with versions in __MigrationsHistory to find initial version (if you have not specified it) and perform all migrations in between initial and target version (if not specified otherwise target is latest version).
I'm not really clear how you did exclude your migration that causes problems, as you need to migrate your database to version before that migration, and then delete and recreate all subsequent migrations from there.
Maybe you could solve your fallback to old version problem by implementing public override void Down() method in your migration that causes problems when trying to rollback? This method can be used to execute code which performs inverse any operations for migration.
Not directly related to question but worth mentioning, there is also pretty detailed tutorial here for EF CF.

How do define the schema that a rails model is set to?

For instance, when I generate an Event model, the table automatically sets to the public schema. How do I specify it to get set to a different schema?
Furthermore, how do you alter the schema of an existing table? Perhaps move it to a different schema?
Thank you!
Disclaimer: I don't know rails, so I'm going to give very postgresql-oriented answers here. For the first part of your question, there is quite possibly a much better way to do this, by making rails specify the schema when creating tables.
In PostgreSQL, tables are searched for in schemas according to the search_path setting. This is set by default to "$user",public. Tables are created in the first schema found in the search path that exists. So if you connect as "my_user", it will try to create tables in "my_user", and fall back to creating them in "public" if "my_user" doesn't exist.
So one approach is to update the "search_path" setting used for the user you connect to the database to make schema changes. For example you can say ALTER USER my_user SET search_path = my_app, public. If you then create a "my_app" schema then subsequent CREATE TABLE foo(...) commands executed by "my_user" will put the new table into "my_app".
You can change the schema of a table using ALTER TABLE foo SET SCHEMA my_app.
Create a migration to generate your new schema. ActiveRecord can't update you schema to you it's the pattern system. You can try sequel or DataMapper if you want update you schema from your code.

Resources