Why use apps.get_model() when creating a data migration? - django-models

As per the django docs when creating django migrations we should use apps.get_model() rather than importing the models and using them.
Why does a data migration have to use the historical version of a model rather than the latest one?(The historical versions of the model will not be in use anyways right?)

It uses the historical versions of the model so that it won't have problems trying to access fields that may no longer exist in the code base when you run your migrations against another database.
If you removed some field from your model and then wanted to run your migrations on some new database, and you were importing your models directly, you can expect your migrations would complain trying to use a field that doesn't exist. When using apps.get_model(...) Django will try to be smart about it and use the definitions of migrations.AddField(...) from your migrations files to give you the correct version of your model at that point in time.
This is also why Django says to be careful about using custom Model/Model Manager methods in your data migrations because I don't believe they can recreate these methods from the migrations history, or the behaviour can change over time and your migrations wouldn't be consistent.

Consider this model:
class A(models.Model):
field1 = models.PositiveIntegerField()
field2 = models.PositiveIntegerField()
Your migration history knows about these two fields and any further migration will consider this model state and will make changes to this model state.
Now suppose, you remove field1 and your model becomes:
class A(models.Model):
field2 = models.PositiveIntegerField()
And in the migration, you try to use field1, django should know that field1 existed. Hence when we use apps.get_model(), it helps django use the previous migrations history and infer about field1. Otherwise you will get an error.

Related

How to update models in asp.net through database first approach while keeping some previous methods alive

I have the following columns in the Patients table:
I've created models using the following command.
Scaffold-DbContext "Server=.;Database=Tasks3;Trusted_Connection=True;"
Microsoft.EntityFrameworkCore.SqlServer
-OutputDir Models\MainModel
Screenshot of Patient Model
I've some methods in context class to make my connection string dynamic. Actually I used to fetch data from tokens and after some logic connection string changes from client to client.
Now the problem is here, when I make changes in patients table (for instance, I changed CNIC column from CNIC5 to CNIC) and run the following command with -Force keyword, it delete all the data from the previous Tasks3Context class (DbContext).
Scaffold-DbContext "Server=.;Database=Tasks3;Trusted_Connection=True;"
Microsoft.EntityFrameworkCore.SqlServer
-OutputDir Models\MainModel -t <Patient> -f
Tell me some method that update models and make changes in only specific model and column.
Thanks in advance!
I tried the database update procedure, and when I used -Force for the second time, there was a problem similar to yours. The specific reasons are as follows:
The code generated by EF Core is your code. Feel free to change it. It will only be regenerated if you reverse engineer the same model again. The scaffolded code represents one model that can be used to access the database, but it's certainly not the only model that can be used.
Customize the entity type classes and DbContext class to fit your needs. For example, you may choose to rename types and properties, introduce inheritance hierarchies, or split a table into multiple entities. You can also remove non-unique indexes, unused sequences and navigation properties, optional scalar properties, and constraint names from the model.
You can also add additional constructors, methods, properties, etc. using another partial class in a separate file. This approach works even when you intend to reverse engineer the model again.
After making changes to the database, you may need to update your EF Core model to reflect those changes. If the database changes are simple, it may be easiest just to manually make the changes to your EF Core model. For example, renaming a table or column, removing a column, or updating a column's type are trivial changes to make in code.
More significant changes, however, are not as easy to make manually. One common workflow is to reverse engineer the model from the database again using -Force (PMC) or --force (CLI) to overwrite the existing model with an updated one.
Another commonly requested feature is the ability to update the model from the database while preserving customization like renames, type hierarchies, etc. Use issue this to track the progress of this feature.
Warning
If you reverse engineer the model from the database again, any changes
you've made to the files will be lost.

Laravel Dynamic Database Table Names

Is there a way to create database tables dynamically in Laravel. I have one Laravel build which has a database schema for quotes using the migrations tool. There will be several customers using the system which need to each have their own database table.
What I would like to happen is that when a function is called by the customer it will use the quotes schema to create a new table like 'customer1_quotes' and use this table for the customer in future. Additionally when migrations are run it will apply the updates to all tables with the given name structure (*_quotes).
If anyone has details to achieve this or a recommend alternative approach please message :)
Create a trait used by observers
Create a trait which loops through your customers and creates/updates the tables. You don't have to be in a migration to call DB::.
Use the trait in create/update controllers or better for model create/update observers. You could also create a console command for manual triggering or testing.
This should not be executed during maintenance. Using php artisan down should ensure no jobs are run during migrations.
The migrations for the customer{id}_quotes tables can loop through the available tables by querying table names using LIKE and/or REGEXP. See link below.
Links
Laravel Model Observers
How to dynamically set table name in Eloquent Model
Laravel's table Blueprint docs (5.8)
Get table names using LIKE or REGEXP
Optimization: Chunking results when getting query builder results
Edit: A repeatable migration probably won't work well and is confusing to others. Using a trait for flexibility to use for an observer is better for this.

Map existing Database table for Laravel

I am looking for a way to map existing tables in a project with the Eloquent ORM and use them in code. I use a MySQL database and plan to migrate to MSSQL. Any way points are appreciated.
You'll have to do this manually.
i.e., create an eloquent model for each of the tables you want access to in your code using eloquent.
If you don't have timestamps named created_at and updated_at, in your model you can disable those columns.
Manually
If you have a users table you could 'map' it with a user.php file in your models folder like this
class User extends Eloquent {
protected $table = 'users';
public $timestamps = false;
}
Via artisan
You can use Jeffrey Ways Laravel Generators to help streamline the initial creation of your models, however you'll still need to make the timestamp modification manually.
This looks like an old post, but it was edited a couple of days ago, so I don't know if the original author is looking for a solution again, but if someone needs this info, here is a packagist package for Laravel 5 to do what you are asking.
Laravel 5 model generator from existing schema:
https://packagist.org/packages/ignasbernotas/laravel-model-generator
Hope that helps someone!
There is also a Eloquent Model Generator library. It can be used for generating Eloquent models using database tables as a source. Generated model will include relation methods, docblocks for magic field and relations and several additional properties.
Another here: https://github.com/Xethron/migrations-generator.
You'll only want to use these generators for local development, so you don't want to update the production providers array in config/app.php. Instead, add the provider in app/Providers/AppServiceProvider.php.
For more details look here - https://packagist.org/packages/ignasbernotas/laravel-model-generator#user-content-installation
You can also use SQL Server Migration Assistant (SSMA) to port the database to SQL Server, but you will still need to write your own models to match the schema.
http://blogs.msdn.com/b/ssma/
http://www.microsoft.com/en-us/download/details.aspx?id=43688
Still this might help get halfway there, from both sides of the puzzle.

Create tabels in Hibernate auto or manually?

Im currently developing a servlet homepage (spring + hibernate + mysql).
Im at the moment using the Hibernate property hibernate.hbm2ddl.auto set to update.
This is working fine and Hibernate creates and updates my tables.
However, Ive have read on multiple places that this is not recommended in production and that it is unsafe.
But if I dont put this option my tables is not created, and I really don't want to create my tabels manually on the server. I got limited time working on this alone.
How is this usually done? It's seems like it is quite much work to add all tables manually imo.
In production, you typically have already existing tables with a large amount of data that you don't want to lose, and that you want to migrate to the new schema. Hibernate can't do that automagically for you. It doesn't know that the data that was previously in column A must now be in the new column B.
So you'll need to create a migration script. Of course, you can use Hibernate to generate the new schema for you in development, see what the differences with the old schema are, and create your script thanks to that. But yes, having an app in production and migrate it needs some work to be done.

Using liquibase, how to handle an object model that is a subset of database table

Some days I love my dba's, and then there is today...
In a Grails app, we use the database-migration plugin (based on Liquibase) to handle migrations etc.
All works lovely.
I have been informed that there is a set of db administrative meta data that we must support on every table. This information has zero use to the app.
Now, I can easily update my models to accommodate this. But that answer is ugly.
The problem is now at each migration, Liquibase/database-migration plugin, complains about the schema and the model being out of sync.
Is there anyway to tell Liquibase (or GORM) that columns x,y,z are to be ignored?
What I am trying to avoid is changesets like this:
changeSet(author: "cwright (generated)", id: "1333733941347-5") {
dropColumn(columnName: "BUILD_MONTH", tableName: "ASSIGNMENT") }
Which tries to bring the schema back in line with the model. Being able to annotate those columns as not applying to the model would be a good thing.
Sadly, you're probably better off defining your own mapping block and taking control of the Data Mapper (what Hibernate essentially is) yourself at this point. If you need to take control of the way the database-integration plugin handles migrations, you might wanna look at the source or raise an issue on the JIRA. Naively, mapping your columns explicitly in the domain model should allow you to bypass unnecessary columns from the DB.

Resources