How can I change the schema of an existing tridion component - schema

I have some component items in tridion which are set up for a particular schema. I'd like to be able to change the schema for those items to a newer schema. The new schema retains all of the existing properties that the old one had, so there would be no data loss. In this situation it is not possible to just alter the existing schema.
Does anyone know if it's possible to do this?

You can change the schema of a component simply by assigning a new value to the Schema property of the component and saving it. Of course, saving the component will require that the component validates against the new schema.
The trivial case for this is when you've just copy-pasted the schema and therefore both schemas are identical. In practice, you generally have a reason for changing the schema, in which case you probably want to use GetXml() and UpdateXml() on the component and have an XSLT transform the XML to something compliant with the new schema. In this scenario, you can simply update the schema reference in your XSLT.
As Jonathon says, you can use a custom page for this, but bear in mind that generally this is a one-time action which should be designed/executed by programmers and administrators, so if you use a custom page, you probably want to remove it afterwards.

There is a reason why the Tridion GUI does not allow you to change the schema on a component: it is very likely that your component will lose its content after such a change, even if the two schemas have some fields in common.
To avoid this, make sure that the schemas have the same target namespace. In that case, if a field is defined in both schemas, the component will retain its values even after the schema has been changed.

The Tridion Content Porter lets you export content and schemas from one CMS to another. It can also be used to move items between publications. This is one option to "duplicate" a schema and its content for re-use (as well as to backup any work before changing live data!).
Be careful not to change the namespace or any XML fields you'd like to keep (descriptions and schema name are okay though). To be sure, especially with live data, do a clean export just in case before using any of these answers.

It is not possible to change the Schema of a Tridion Component through the Content Manager interface. However, this can be achieved using a 'Custom Page' as the API allows the changing of a Component's Schema through code.
Taken from the SDL Tridion 2009 documentation (Templating Implementation Manual (TOM.NET) 2009):
Class: Tridion.ContentManager.ContentManagement.Component
Property: public Schema Schema { get; set; }
Description: Get or set the Schema for the Component's content and metadata.
There is an item (including a code sample) on the Tridion developer forums (TOPIC_ID=2899) about this. However, as this is a closed forum I am unsure about the legalities of reproducing the code here.

I was able to do this by writing some queries to replace the schema names and references directly within the tridion database. It worked fine, but I would only recommend this if the starting schema is EXACTLY like the end schema. Otherwise it'll break the components.

Related

How should I modify database model in Entity Framework?

EF beginner here.
How am I supposed to make changes in database model using Entity Framework?
I mean in DB model like changing datatypes of columns, adding attributes etc.?
E.g. I have string Password property in User table and I want to add [DataType(DataType.Password)] Attribute or [Required] or anything.
How am I supposed to do that? Of course along with applying changes to my DB? I created DB model from mdf local file (detached from mssql studio) using 'EF Designer from database' so I have my emdx model inside Models (asp.net mvc5) with classes for each table and DB MDF in App_Data.
Am I suppose to modify these classes?
Because I can add attributes right there but Diagram doesn't change and DB doesn't change. I guess I have to commit changes somehow.
I'll add that I can't enable migrations:
Creating a DbModelBuilder or writing the EDMX from a DbContext created using Database First or Model First is not supported.
EDMX can only be obtained from a Code First DbContext created without using an existing DbCompiledModel.
I think you are mixing allot of things here.
If you have an EDMX file, then your models are generated at compile time (or you can generate them from right click on the Model.tt file -> Run Custom Tool). So adding attributes to properties in a class representing a model entity will indeed be overwritten the next time you compile. The solution is:
Create another partial class to the generated classes
In the partial class, decorate the class with the [MetadataType] attribute and give it a type of a metadata class. The metadata class is a simple class, with the same properties as the generated class, but a different name, to prevent naming conflicts. From a design point of view, it should be abstract, because you're not supposed to create instances of it, but this is not required.
In the metadata class, decorate the matching properties with the validation and DataType attributes.
To the best of my knowledge, using model-first or database-first doesn't support migrations as in code-first. If you want to make changes to your schema (semi) automatically, I believe your best option is:
Make changes to your model in the EDMX designer
Right-click on the EDMX design surface -> Generate Database from Model.
After selecting the connection to your database, this will generate the SQL to generate your schema. This is a bit clunky, because it will erase your data each time, so you should have a script in place to re-populate your database after each time.

Can Liquibase handle multiple schemas managed by the same application?

We are developing an application which uses multiple schemas to manage database objects.
I cannot see anyway of doing this with Liquibase.
I had to drop schemas manually and create them.
dropAll gradle task only drops objects in public schema.
Any help would be great.
Thanks for your time.
Liquibase can handle objects within multiple schemas and can also manage creating additional schemas as well.
When you connect to the database, Liquibase will create a DATABASECHANGELOG table in the default schema and that schema needs to exist. That table tracks which changeSets have executed, and anything that can be done through SQL can be done within your changeSets.
There are built-in tags for things like createTable, addColumn etc which will make changes in the default schema, but they all have tags such as tableSchemaName that can be used to target the object to a different schema.
If you want to make changes for which there are not built-in tags, you can always use the "sql" tag and specify whatever sql you want, such as create database additional_info

Sql Azure CompatibleWithModel not working

In my code I am trying to check if my entity framework Code First model and Sql Azure database are in sync by using the "mycontext.Database.CompatibleWithModel(true)". However when there is an incompatibility this line falls over with the following exception.
"The model backing the 'MyContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data."
This seems to defeat the purpose of the check as the very check itself is falling over as a result of the incompatibility.
For various reasons I don't want to use the Database.SetInitializer approach.
Any suggestions?
Is this a particular Sql Azure problem?
Thanks
Martin
Please check out the ScottGu blog below:
http://weblogs.asp.net/scottgu/archive/2010/08/03/using-ef-code-first-with-an-existing-database.aspx
Here is what is going on and what to do about it:
When a model is first created, we run a DatabaseInitializer to do things like create the database if it's not there or add seed data. The default DatabaseInitializer tries to compare the database schema needed to use the model with a hash of the schema stored in an EdmMetadata table that is created with a database (when Code First is the one creating the database). Existing databases won’t have the EdmMetadata table and so won’t have the hash…and the implementation today will throw if that table is missing. We'll work on changing this behavior before we ship the fial version since it is the default. Until then, existing databases do not generally need any database initializer so it can be turned off for your context type by calling:
Database.SetInitializer<Production>(null);
Using above code you are no recreating the database instead using the existing one so I don't think using Database.SetInitializer is a concern unless you have some serious thoughts about using it.
More info: Entity Framework Code Only error: the model backing the context has changed since the database was created

custom table in Ektron database

I am adding a custom table to an Ektron database. What is the best practice for connecting to the database? Using standard ADO.NET code or is there a way to use the CMS' connection to the database? What is best practice?
Ektron 8.0.1 SP1
Adding Custom tables to the Ektron Database will not cause any issues,there is no need of another Database if you are having only few custom tables to be added.
Altering the Ektron tables will create issues,so it is better not to go for that.
For accessing data from the Custom Tables make use of LINQ (refer:here).
I know this question is a little old and answered, but I wanted to add my two cents. While altering Ektron's tables isn't advised (that is, without the API or scripts they've provided), adding your own table does no harm. If Ektron didn't support it they wouldn't provide the "Sync Custom Tables" option in eSync.
I came across this and thought that I could add a little to the discussion in case anyone is considering adding a custom table to the Ektron database. I think this topic is still relevant to the current version of Ektron and could be helpful.
Here are some good points:
Do not alter tables created by Ektron. (Point made by Bisileesh extended comment below)
Adding custom tables to the Ektron database is recommended in certain circumstances.
Using a smart form for content may be recommended but there are times when it is not optimal.
Here are some reasons why I say these things:
You should not alter tables created by Ektron for several reasons. Basically you don't want to change these because the Ektron software relies on these tables and modifications could cause errors. Besides the possibility of breaking things, if you ever upgrade Ektron, the Ektron Update may alter table definitions and erase your changes.
Adding tables to the existing Ektron database is a good idea when compared to adding a new database for several reasons.
First, you don't incur the additional cost of a full database structure on your server when you add a table.
Second if you are working in a multiple server environment (development, staging, live) by adding your tables to the Ektron database you will be able to use eSync to manage transferring the data between servers. If you use your own database, you will need to manage synchronization elsewhere.
I started with the idea that it was better to use my own database, but over the years I have discovered the advantages of using the Ektron database. Just as if you were using your own database, you should save the scripts to create the custom tables and perform database backups on a regular basis to ensure that you are protected.
After doing Ektron upgrades you should ensure that your customized tables are still present in the Ektron database.
When setting up eSync for custom tables I had to first run the sync on an empty table. After running the sync to establish a relationship, I was able to add data. There is also a requirement that there be a primary key on the custom tables and I don't think it can be an auto-incremented field. Consult Ektron for the latest requirements.
When considering whether to add data to a smart form or a custom table here are some things to consider. If you use the Smart Form you are committing to using the Ektron provided controls to access your data. This may be a good thing or a bad thing depending on your requirements and the current state of Ektron.In my case, search was a big deal. In versions 7.6 and 8.0 there were problems with the Ektron Search and it was no easy to do boolean searches across multiple fields. To overcome this I used custom tables that I could directly query. The search in version 8.6 has been changed but I still use my custom solution so I don't know if things are working better now.There are other data management issues that come up with smart forms and the Ektron Workarea that make it a good idea to avoid smart forms in some other cases too. The best place to store your data is not one place or the other, it depends on your requirements.
Best practice is to not use custom tables. If you can store your data as smart forms, users can use the workarea to edit their data. If you have to use a custom table, there are several ways:
One way is to pull the connection string from the web.config in an ASPX page
<asp:SqlDataSource ID="EktronSqlDataSource" runat="server" ConnectionString="<%$ConnectionStrings:Ektron.DBConnection %>" ></asp:SqlDataSource>
I'd look at using a different database. As mentioned by maddoxej, Ektron doesn't really like you messing with SQL and tables and what-not.
Granted, you may have admin reasons for using one database, but for the sake of maintainability I think it's worth having a second database which you fully control.
You can add custom tables without effecting existing ones. But to use them you need custom controls each time. Like custom layouts, custom forms, custom widgets.

What are the Best Practices to follow while creating a data-dictionary?

I have large and complex SQL Server 2005 DB used by multiple applications. I want to create a data-dictionary for maintaining not only my DB objects but also cross-reference them against applications that use a specific object.
For example, if a stored procedure is used by 15 diffrent applications I want to record that additional data too.
What are the key elements to be kept in mind so that I get a efficient and scalable Data Dictionary?
So, I recently helped to build a data dictionary for a very large product. We were dealing with documenting more than one-thousand tables using a change request process. I can send you a scrubbed version of the spreadsheet we used if you want. Basically, we captured the following:
Column Name
Data Type
Length
Scale (for decimals)
Whether the column is custom for the application(s) or a default column
Which application(s)/component(s) the column is used in
Release the column was introduced in
Business definition
We also captured information about who requested the addition, their contact information, etc. Our primary focus was on business definition, and clearly identifying why a column was being used or created.
We didn't have stored procedures in our solution, but bear in mind that these would be pretty easy to add to the system.
We used Access for our front-end, even though SQL Server was on the back end. It made it pretty easy for us to build out a rich user interface without much work, using the schema we had already built out.
Hope this helps you get started--feel free to ask if you have additional questions.
I've always been a fan of using the 'extended properties' within SQL Server for storing this kind of meta data. In this way the description of each object lives alongside the object and is accessible by anyone with access to the database itself. I'm sure there are also tools out there that can read these extended properties and turn them into a nicely formatted document.
As far as being "scalable", I don't know of any issues related to adding large amounts of data as extended properties; or I should say I've never had any issues with this.
You can set these extended properties using SQL Server Management Studio 'property' dialog for each table/proc/function/etc and can also use the 'sp_addextendedproperty'.