We have a Grails project that needs to pull data from a SQL Server 2008 view. We just need to do a basic select from the view.
Is there a config setting for views such that we can map a domain class to the view?
Or should we use raw SQL like:
db.rows("SELECT foo, bar FROM my_view")
You can use SQL, e.g. with groovy.sql.Sql as suggested in the other similar question's answer, but it's also possible in a domain class. If you create a domain class (use any sensible name) and specify its table name as the name of the view, you can select from it. You'll have problems creating and updating of course, but if you only want to read then it'll be fine:
class SomeDomainClass {
String foo
Integer bar
static mapping = {
table 'my_view'
}
}
If you name the class MyView then mapping isn't needed since the naming convention applies, but this would be a bad name for the class since using it isn't related to the fact that it's backed by a view.
Note that you'll also have problems when using dbCreate set to "create", "create-drop", or "update" since Hibernate will try to create the table, but it shouldn't cause any real problem and just display an ignorable error like "could not create table 'my_view' since it already exists". And once you move to using database migrations this won't be a problem at all.
Related
Yesterday I asked this question about changing the name of the __Migration History table generated by Entity Framework when using a Code First approach. The provided link was helpful in saying how to do what we want (and by "want" I mean what we're being forced into by our DBAs), however also left a somewhat non-specific and dire-sounding warning that says,
Words of precaution
Changing the migration history table is powerful but you need to be
careful to not overdo it. EF runtime currently does not check whether
the customized migrations history table is compatible with the
runtime. If it is not your application may break at runtime or behave
in unpredictable ways. This is even more important if you use multiple
contexts per database in which case multiple contexts can use the same
migration history table to store information about migrations.
We tried to use this warning to reason with the DBA team, telling them that we shouldn't mess with things because "here be dragons". Their response was, "It sounds more like the danger is in changing the content or the table structure, not the name. Go ahead and try it and see what happens."
Has anyone here changed the name of the __Migrations History table, and what was the result? Is it dangerous?
Changing the name of the migrations history table is possible.
But you have to tell EF this by calling the HasDefaultSchema method with the name of the schema in the OnModelCreating method of your DbContext class:
public partial class CustomerDatabasesModel : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("CustomerDatabases");
// Fluent API configuration
}
}
This the will cause EF to create a "CustomerDatabases" prefix for all database tables.
So in this example "CustomerDatabases" replaces the standard of "dbo" prefix of your tables. Your migration history table will be have the name CustomerDatabases.__MigrationHistory.
So in fact, you change the owner name of the database (the first part), the second part "__MigrationHistory" stays the same.
Usage scenario:
You usually do this, if you work with more than one DbContext.
So you can have more than one MigrationHistory table in a single database, one for each context.
Of cause you should carefully test this and perform database backups before.
Please check out this answer too:
Entity-Framework: On Database, multiple DbContexts
I'd like to use SQL OUTPUT clause to keep history of the records on my database while I'm using Entity Framework. To achieve this, EF needs to generate the following example for a DELETE statement.
Delete From table1
output deleted.*, 'user name', getdate() into table1_hist
Where field = 1234;
The table table1_hist has the same columns as table1, with the addition of two columns to store the name of the user who did the action and when it happened. However, EF doesn't seem to have a way to support this SQL Server's clause, so I'm lost on how to implement that.
I looked at EF's source code, and the DELETE command is create inside a internal static method (GenerateDeleteSql in System.Data.Entity.SqlServer.SqlGen.DmlSqlGenerator class), so I can't extend the class to add the behavior I want. It looks like I'll have to rewrite the SQL Server provider based on the existing code, but that is something I'd like to avoid...
So, my question is if there's another option to do this (an extension, for example) or do I have to rewrite this provider?
Thank you.
Have you considered either
Using Stored Procedures to encapsulate your data logic
A delete trigger to capture the data
Change Data Capture (Enterprise edition only)
not actually deleting the data - merely setting a flag in the data to mark it as deleted.
I am using RIA Services with Silverlight and Entity Framework. I want to call a stored procedure and map the results to a datagrid. What is the best way to do this? The output of the stored procedure doesn't map to any table design.
I found the following article -
http://blogs.msdn.com/b/tom/archive/2009/05/07/silverlight-ria-calling-stored-procedures-that-don-t-return-tables.aspx
However, it doesn't work for me - I get an error saying that the result complex set does not have a primary key defined. I can't see how to define this in code.
Anyway, I'm open to any and all solutions.
I found the following excellent step-by-step guide at this site -
http://betaforums.silverlight.net/forums/p/218383/521023.aspx
1) Add a ADO Entity Data Model to your Web project; Select generate from database option; Select your Database instance to connect to.
2) Choose your DB object to import to the Model. You can expand Table node to select any table you want to import to the Model. Expand Stored Procedure node to select your Stored Precedure as well. Click Finish to finish the import.
3) Right click the DB model designer to select Add/Function Import. Give the function a name (same name as your SP would be fine) and select the Stored Procedure you want to map. If your SP returns only one field, you can map the return result to a collection of scalars. If your SP returns more than one field, you could either map the return result to a collection or Entity (if all the field are from a single table) or a collection of Complex types.
If you want to use Complex type, you can click Get Column button to get all the columns for your SP. Then click Create new Complex type button to create this Complex type.
4) Add a Domain Service class to the Web project. Select the DataModel you just created as the DataContext of this Service. Select all the entitis you want expose to the client. The service functions should be generated for those entities.
5) You may not see the Complex type in the Entity list. You have to manully add a query function for your SP in your Service:
Say your SP is called SP1, the Complex type you generated is called SP1_Result.
Add the following code in your Domain Service class:
public IQueryable<SP1_Result> SP1()
{
return this.ObjectContext.SP1().AsQueryable();
}
Now you can compile your project. You might get an error like this: "SP1_Result does not have a Key" (if you not on RIA service SP1 beta). If you do, you need to do the following in the service metadata file:
Added a SP1_Result metadata class and tagged the Key field:
[MetadataTypeAttribute(typeof(SP1_Result.SP1_ResultMetadata))]
public partial class SP1_Result
{
internal sealed class SP1_ResultMetadata
{
[Key]
public int MyId; // Change MyId to the ID field of your SP_Result
}
}
6) Compile your solution. Now you have SP1_Result exposed to the client. Check the generated file, you should see SP1_Result is generated as an Entity class. Now you can access DomainContext.SP1Query and DomainContext.SP1_Results in your Silverlight code. You can treat it as you do with any other Entity(the entity mapped to a table) class.
Well, I figured out how to do it, though it's a bit messy. You need to create a metadata class for the result set in the domain metadata file. After that, RIA will treat it essentially like it does an entity.
Full details can be found here - http://leeontech.wordpress.com/2010/05/24/ria-services-and-storedprocedures/
In python::Pylons i'm able to issue a setup-app command and it will look at my Models and issue the appropriate CREATE TABLE or CREATE INDEX ddl for my particular database.
it seems like this would be a feature in CakePHP, but i'm having trouble finding it.
in fact i see this in the manual:
"You can create your database tables as you normally would. When you create your Model classes, they'll automatically map to the tables that you've created."
which leads me to believe it doesn't exist?
No, it's other way around - you can create models, controllers and views by having DB schema. It's more logical to have a DB design schema first.
Check this out
Some of the comments in the accepted answer above lead me to creating this answer. You can technically create new tables on the fly using the YourModel->query() function. I am currently using this in a Behavior I am writing. This works in CakePHP 2.x, pretty sure it works in 1.3 as well.
In the setup function for the Behavior I am checking to see if the table already exists. If it doesn't I create it.
$dataSource = ConnectionManager::getDataSource('your DB');
if(!in_array($tableName, $dataSource->listSources()){
$this->createYourTableFunction();
}
In the createYourTableFunction you create a temporary model to run the YourModel->query() against. And just provide it your SQL instructions. When creating your temporary model just set the table parameter to false so you don't get a missing table error.
$YourModel = new Model(array('table' => false, 'name' => 'YourModel', 'ds' => 'Your DB'));
$YourModel->query('SQL instruction string');
Are there any rapid Database protoyping tools that don't require me to declare a database schema, but rather create it based on the way I'm using my entities.
For example, assuming an empty database (pseudo code):
user1 = new User() // Creates the user table with a single id column
user1.firstName = "Allain" // alters the table to have a firstName column as varchar(255)
user2 = new User() // Reuses the table
user2.firstName = "Bob"
user2.lastName = "Loblaw" // Alters the table to have a last name column
Since there are logical assumptions that can be made when dynamically creating the schema, and you could always override its choices by using your DB tools to tweak it later.
Also, you could generate your schema by unit testing it this way.
And obviously this is only for prototyping.
Is there anything like this out there?
Google's Application Engine works like this. When you download the toolkit you get a local copy of the database engine for testing.
Grails uses Hibernate to persist domain objects and produces behavior similar to what you describe. To alter the schema you simply modify the domain, in this simple case the file is named User.groovy.
class User {
String userName
String firstName
String lastName
Date dateCreated
Date lastUpdated
static constraints = {
userName(blank: false, unique: true)
firstName(blank: false)
lastName(blank: false)
}
String toString() {"$lastName, $firstName"}
}
Saving the file alters the schema automatically. Likewise, if you are using scaffolding it is updated. The prototype process becomes run the application, view the page in your browser, modify the domain, refresh the browser, and see the changes.
I agree with the NHibernate approach and auto-database-generation. But, if you want to avoid writing a configuration file, and stay close to the code, use Castle's ActiveRecord. You declare the 'schema' directly on the class with via attributes.
[ActiveRecord]
public class User : ActiveRecordBase<User>
{
[PrimaryKey]
public Int32 UserId { get; set; }
[Property]
public String FirstName { get; set; }
}
There are a variety of constraints you can apply (validation, bounds, etc) and you can declare relationships between different data model classes. Most of these options are parameters added to the attributes. It's rather simple.
So, you're working with code. Declaring usage in code. And when you're done, let ActiveRecord create the database.
ActiveRecordStarter.Initialize();
ActiveRecordStarter.CreateSchema();
May be not exactly responding to your general question, but if you used (N)Hibernate then you can automatically generate the database schema from your hbm mapping files.
Its not done directly from your code as you seem to be wanting but Hibernate Schema generation seems to work well for us
Do you want the schema, but have it generated, or do you actually want NO schema?
For the former I'd go with nhibernate as #tom-carter said. Have it generate your schema for you, and you are all good (atleast until you roll your app out, then look at something like Tarantino and RedGate SQL Diff or whatever it's called to generate update scripts)
If you want the latter.... google app engine does this, as I've discovered this afternoon, and it's very nice. If you want to stick with code under your control, I'd suggest looking at CouchDB, tho it's a bit of upfront work getting it setup. But once you have it, it's a totally, 100% schema-free database. Well, you have an ID and a Version, but thats it - the rest is up to you. http://incubator.apache.org/couchdb/
But by the sounds of it (N)hibernate would suite the best, but I could be wrong.
You could use an object database.