How to add django-mptt rebuild to migration? - django-migrations

I have add the django-mptt to existing database, and create the new migration.
Migration process was asked for default values for level, left, right and such fields, but doesn't add the model.rebuild operation to migration file.
How to add rebuild operation to migration file manually?

Try the following:
from __future__ import unicode_literals
from django.db import migrations
from mptt import register, managers
def rebuild_tree(apps, schema_editor):
YourMPTTModel = apps.get_model('your_app', 'YourMPTTModel')
manager = managers.TreeManager()
manager.model = YourMPTTModel
register(YourMPTTModel)
manager.contribute_to_class(YourMPTTModel, 'objects')
manager.rebuild()
class Migration(migrations.Migration):
operations = [
migrations.RunPython(
rebuild_tree
)
]

Related

Epsilon Model Migration (Flock) - Full Copy

in the webpage of Epsilon Model Migration Language (https://www.eclipse.org/epsilon/doc/flock/) there is the description of the "Full Copy" primitive. I want to use it to copy a model in the simplest possible way, generating a new model with another name (but essentially is a full copy of the first one). Can you show me some pieces of code? Is my first time with Epsilon. Thanks.
Below is a minimal example that demonstrates running Flock from Java to migrate an EMF-based tree model. The complete Maven project is in Epsilon's Git repo.
package org.eclipse.epsilon.examples.standalone.flock;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.eclipse.epsilon.emc.emf.EmfModel;
import org.eclipse.epsilon.flock.FlockModule;
public class FlockStandaloneExample {
public static void main(String[] args) throws Exception {
Path root = Paths.get(FlockStandaloneExample.class.getResource("").toURI()),
modelsRoot = root.getParent().resolve("models");
// Set up the original model
EmfModel original = new EmfModel();
original.setName("Source");
original.setReadOnLoad(true);
original.setStoredOnDisposal(false);
original.setMetamodelFile(modelsRoot.resolve("Tree.ecore").toAbsolutePath().toString());
original.setModelFile(modelsRoot.resolve("Tree.xmi").toAbsolutePath().toString());
original.load();
// Set up the migrated model
EmfModel migrated = new EmfModel();
migrated.setName("Migrated");
migrated.setReadOnLoad(false);
migrated.setStoredOnDisposal(true);
migrated.setMetamodelFile(modelsRoot.resolve("Tree.ecore").toAbsolutePath().toString());
migrated.setModelFile(modelsRoot.resolve("Tree.migrated.xmi").toAbsolutePath().toString().replace("/target/classes/", "/src/"));
migrated.load();
// Run the migration transformation
FlockModule module = new FlockModule();
module.parse(root.resolve("tree2tree.mig"));
module.getContext().getModelRepository().addModel(original);
module.getContext().getModelRepository().addModel(migrated);
module.getContext().setOriginalModel(original);
module.getContext().setMigratedModel(migrated);
module.execute();
// Save the migrated model
module.getContext().getModelRepository().dispose();
}
}

mscrm import update columnmapping reference attribute

I work on Dynamics 365 and I need to develop a dynamics update of records using the Import Entity.
I manage to make a dynamics import to create record into Dynamics 365 but for update I have that message :
"This attribute is not mapped as a reference attribute. However, you have included a ReferenceMap for it. Fix this inconsistency, and then import this data map again."
Well, I don't find any documentation even in SDK even on web even on Microsoft website. I hope to find help from you guys ;)
See my code about columnmapping of my reference ID mapping :
Entity colMapping = new Entity(CrmColumnmapping.EntityLogicalName);
colMapping.Attributes.Add(CrmColumnmapping.Fields.SourceAttributeName, dc.Caption);
colMapping.Attributes.Add(CrmColumnmapping.Fields.SourceEntityName, "MySource");
colMapping.Attributes.Add(CrmColumnmapping.Fields.TargetAttributeName, dc.ColumnName);
colMapping.Attributes.Add(CrmColumnmapping.Fields.TargetEntityName, dt.TableName);
colMapping.Attributes.Add(CrmColumnmapping.Lookups.ImportMapId, new EntityReference(CrmImportmap.EntityLogicalName, importMap.Id));
colMapping.Attributes.Add(CrmColumnmapping.OptionSets.ProcessCode, new OptionSetValue(CrmColumnmapping.OptionSets.ProcessCodeValues.Option1_Process));
colMapping.Id = service.Create(colMapping);
Entity parentLookupMapping = new Entity(CrmLookupmapping.EntityLogicalName);
parentLookupMapping.Attributes.Add(CrmLookupmapping.Lookups.ColumnMappingId, colMapping.ToEntityReference());
parentLookupMapping.Attributes.Add(CrmLookupmapping.OptionSets.ProcessCode, new OptionSetValue(CrmLookupmapping.OptionSets.ProcessCodeValues.Option1_Process));
parentLookupMapping.Attributes.Add(CrmLookupmapping.Fields.LookUpAttributeName, dc.Namespace + "id");
parentLookupMapping.Attributes.Add(CrmLookupmapping.Fields.LookUpEntityName, dc.Namespace);
parentLookupMapping.Attributes.Add(CrmLookupmapping.OptionSets.LookUpSourceCode, new OptionSetValue(CrmLookupmapping.OptionSets.LookUpSourceCodeValues.Option2_System));
parentLookupMapping.Id = service.Create(parentLookupMapping);
Entity currentLookUpMapping = new Entity(CrmLookupmapping.EntityLogicalName);
currentLookUpMapping.Attributes.Add(CrmLookupmapping.Lookups.ColumnMappingId, colMapping.ToEntityReference());
currentLookUpMapping.Attributes.Add(CrmLookupmapping.OptionSets.ProcessCode, new OptionSetValue(CrmLookupmapping.OptionSets.ProcessCodeValues.Option1_Process));
currentLookUpMapping.Attributes.Add(CrmLookupmapping.Fields.LookUpAttributeName, dc.ColumnName);
currentLookUpMapping.Attributes.Add(CrmLookupmapping.Fields.LookUpEntityName, dt.TableName);
currentLookUpMapping.Attributes.Add(CrmLookupmapping.OptionSets.LookUpSourceCode, new OptionSetValue(CrmLookupmapping.OptionSets.LookUpSourceCodeValues.Option1_Source));
currentLookUpMapping.Id = service.Create(currentLookUpMapping);
See my code about import :
Entity import = new Entity(CrmImport.EntityLogicalName);
import.Attributes.Add(CrmImport.OptionSets.ModeCode, new OptionSetValue(CrmImport.OptionSets.ModeCodeValues.Option2_Update));
import.Attributes.Add(CrmImport.Fields.Name, "UpdateImport");
import.Id = service.Create(import);
If someone know how to map the reference attribute (ex : systemuserid) to manage to make a dynamics update import, it will be appreciated.
Thanks a lot

Flyway Spring Boot Autowired Beans with JPA Dependency

I am using Flyway 5.0.5 and I am unable to create a java (SpringJdbcMigration) with autowired properties... They end up null.
The closest thing I can find is this question: Spring beans are not injected in flyway java based migration
The answer mentions it being fixed in Flyway 5 but the links are dead.
What am I missing?
I struggled with this for a long time due to my JPA dependency. I am going to edit the title of my question slightly to reflect this...
#Autowired beans are instantiated from the ApplicationContext. We can create a different bean that is ApplicationContextAware and use that to "manually wire" our beans for use in migrations.
A quite clean approach can be found here. Unfortunately, this throws an uncaught exception (specifically, ApplicationContext is null) when using JPA. Luckily, we can solve this by using the #DependsOn annotation and force flyway to run after the ApplicationContext has been set.
First we'll need the SpringUtility from avehlies/spring-beans-flyway2 above.
package com.mypackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
#Component
public class SpringUtility implements ApplicationContextAware {
#Autowired
private static ApplicationContext applicationContext;
public void setApplicationContext(final ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/*
Get a class bean from the application context
*/
public static <T> T getBean(final Class clazz) {
return (T) applicationContext.getBean(clazz);
}
/*
Return the application context if necessary for anything else
*/
public static ApplicationContext getContext() {
return applicationContext;
}
}
Then, configure a flywayInitializer with a #DependsOn for springUtility. I extended the FlywayAutoConfiguration here hoping to keep the autoconfiguration functionality. This mostly seems to have worked for me, except that turning off flyway in my gradle.build file no longer works, so I had to add the #Profile("!integration") to prevent it from running during my tests. Other than that the autoconfiguration seems to work for me but admittedly I've only run one migration. Hopefully someone will correct me if I am wrong.
package com.mypackage;
import org.flywaydb.core.Flyway;
import org.springframework.boot.autoconfigure.flyway.FlywayMigrationInitializer;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration.FlywayConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.DependsOn;
import com.mypackage.SpringUtility;
#Configuration
#Profile("!integration")
class MyFlywayConfiguration extends FlywayConfiguration {
#Primary
#Bean(name = "flywayInitializer")
#DependsOn("springUtility")
public FlywayMigrationInitializer flywayInitializer(Flyway flyway){
return super.flywayInitializer(flyway);
//return new FlywayMigrationInitializer(flyway, null);
}
}
And just to complete the example, here is a migration:
package db.migration;
import org.flywaydb.core.api.migration.spring.BaseSpringJdbcMigration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import com.mypackage.repository.AccountRepository;
import com.mypackage.domain.Account;
import com.mypackage.SpringUtility;
import java.util.List;
public class V2__account_name_ucase_firstname extends BaseSpringJdbcMigration {
private AccountRepository accountRepository = SpringUtility.getBean(AccountRepository.class);
public void migrate(JdbcTemplate jdbcTemplate) throws Exception {
List<Account> accounts = accountRepository.findAll();
for (Account account : accounts) {
String firstName = account.getFirstName();
account.setFirstName(firstName.substring(0, 1).toUpperCase() + firstName.substring(1));
account = accountRepository.save(account);
}
}
}
Thanks to avehlies on github, Andy Wilkinson on stack overflow and OldIMP on github for helping me along the way.
In case you are using more recent versions of Flyway, then extend BaseJavaMigration instead of BaseSpringJdbcMigration as the later is deprecated. Also, take a look at the below two comments by the user Wim Deblauwe.
The functionality hasn't made it into Flyway yet. It's being tracked by this issue. At the time of writing that issue is open and assigned to the 5.1.0 milestone.
Seems the updated answer provided by #mararn1618 is under documented on the official documentation, so I will provide a working setup here. Thanks to #mararn1618 for guiding in that direction.
Disclaimer, it's written in Kotlin :)
First you need a configuration for loading the migration classes, in Spring Boot (and perhaps Spring) you need either an implementation of FlywayConfigurationCustomizer or a setup of FlywayAutoConfiguration.FlywayConfiguration. Only the first is tested, but both should work
Configuration a, tested
import org.flywaydb.core.api.configuration.FluentConfiguration
import org.flywaydb.core.api.migration.JavaMigration
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.autoconfigure.flyway.FlywayConfigurationCustomizer
import org.springframework.context.ApplicationContext
import org.springframework.stereotype.Component
#Component
class MyFlywayConfiguration #Autowired constructor(
val applicationContext: ApplicationContext
) : FlywayConfigurationCustomizer {
override fun customize(configuration: FluentConfiguration?) {
val migrationBeans = applicationContext.getBeansOfType(JavaMigration::class.java)
val migrationBeansAsArray = migrationBeans.values.toTypedArray()
configuration?.javaMigrations(*migrationBeansAsArray)
}
}
Configuration option B, untested, but should also work
import org.flywaydb.core.api.migration.JavaMigration
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration
import org.springframework.boot.autoconfigure.flyway.FlywayConfigurationCustomizer
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
#Configuration
class MyFlywayConfiguration : FlywayAutoConfiguration.FlywayConfiguration() {
#Bean
fun flywayConfigurationCustomizer(applicationContext: ApplicationContext): FlywayConfigurationCustomizer {
return FlywayConfigurationCustomizer { flyway ->
val p = applicationContext.getBeansOfType(JavaMigration::class.java)
val v = p.values.toTypedArray()
flyway.javaMigrations(*v)
}
}
}
And with that you can just write your migrations as almost any other Spring bean:
import org.flywaydb.core.api.migration.BaseJavaMigration
import org.flywaydb.core.api.migration.Context
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
#Component
class V7_1__MyMigration #Autowired constructor(
) : BaseJavaMigration() {
override fun migrate(context: Context?) {
TODO("go crazy, mate, now you can import beans, but be aware of circular dependencies")
}
}
Side notes:
Be careful of circular dependencies, your migrations can most likely not depend on repositories (also makes sense, you are preparing them, after all)
Make sure your migrations are located where Spring scans for classes. So if you want to place them in the namespace db/migrations, you need to ensure that Spring scans that location
I haven't tested, but it's likely one should be cautious with mixing the path for these migrations and the locations where Flyway scans for migrations
Current flyway 6.5.5 version is released and back from 6.0.0 I believe support for spring beans is provided.
You can directly autowire spring beans into your Java based migrations (using #autowired), But the hunch is your Migration class also should be managed by Spring to resolve dependency.
There is a cool and simple way for it, by overriding default behavior of Flyway, check out https://reflectoring.io/database-migration-spring-boot-flyway/
the article clearly answers your question with code snippets.
If you are using deltaspike you can use BeanProvider to get a reference to your DAO.
Change your DAO code:
public static UserDao getInstance() {
return BeanProvider.getContextualReference(UserDao.class, false, new DaoLiteral());
}
Then in your migration method:
UserDao userdao = UserDao.getInstance();
And there you've got your reference.
(referenced from: Flyway Migration with java)

Using restframework mongoengine how to create a queires?

models.py
from mongoengine import Document, fields
class Tool(Document):
Fruit = fields.StringField(required=True)
District = fields.StringField(required=True)
Area = fields.StringField(required=True)
Farmer = fields.StringField(required=True)
Serializers.py file
from rest_framework import serializers
from rest_framework_mongoengine.serializers import DocumentSerializer
from models import Tool
class ToolSerializer(DocumentSerializer):
class Meta:
model = Tool
views.py file
from django.template.response import TemplateResponse
from rest_framework_mongoengine.viewsets import ModelViewSet as MongoModelViewSet
from app.serializers import *
def index_view(request):
context = {}
return TemplateResponse(request, 'index.html', context)
class ToolViewSet(MongoModelViewSet):
lookup_field = 'Fruit'
serializer_class = ToolSerializer
def get_queryset(self):
return Tool.objects.all()
So,I want to create queries like http://127.0.0.1:8000/api/tool/?Fruit=Banana gives me all data for fruit banana only. Also, http://127.0.0.1:8000/api/tool/?District=Pune gives me data for Pune district only .
Unfortunately, I haven't tried this solution myself yet, but AFAIK, in pure DRF with SQL database you'd use Django-Filters package for this.
There's an analogue of it for DRF-ME, called drf-mongo-filters, written by Maxim Vasiliev, co-author of DRF-ME. It contains a decent set of tests, you could use for inspiration.
Basically, you say something like:
from rest_framework.test import APIRequestFactory
from rest_framework.generics import ListAPIView
from mongoengine import Document, fields
from drf_mongo_filters.filtersets import filters, Filterset, ModelFilterset
from drf_mongo_filters.backend import MongoFilterBackend
class TestFilter(Filterset):
foo = filters.CharFilter()
class TestView(ListAPIView):
filter_backends = (MongoFilterBackend,)
filter_class = TestFilter
serializer_class = mock.Mock()
queryset = mock.Mock()
TestView.as_view()(APIRequestFactory().get("/?foo=Foo"))
TestView.queryset.filter.assert_called_once_with(foo="Foo")
Haven't tried doing the same with ViewSets, but as they inherit from GenericView, I guess, they should respect filter_class and filter_backends parameters, too.

How to retrieve dynamic content from database?

I'm evaluating java-based cms and selecting one as our cms ,now I'm learning dotcms , I need to know how to retrieve content from db like traditional jsp/bo does,I'm new to dotcms, the official documents only tell how to add static content but dynamic content , say running a sql and getting the wanted data ,then putting them into pages. We are doing an internal website where employees can browse news, events, colleagues information etc which managed through a cms, the information is definitely dynamic and updated regularly. We plan to use spring mvc on the project. Any ideas on the question?
thank you.
To get this to work you need to do a few things:
If you want to use a different database, then you can add a new resource to the conf/Catalina/localhost/ROOT.xml file. If you want to use the dotCMS database to host the additional tables then you can skip this step.
From within your java code you can get a database connection using the DbConnectionFactory class. Now you can read the data from the database. Here's an example:
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
Connection conn = DbConnectionFactory.getConnection();
Statement selectStatement;
try {
selectStatement = conn.createStatement();
try {
selectStatement.execute("SELECT * FROM your_table WHERE your_where_clause etc...");
ResultSet result = selectStatement.getResultSet();
if (result.next()) {
.. do your stuff here...
// for example:
// Long dbId = result.getLong("Id");
// String stringField = result.getString("stringFieldName");
// int intField = result.getInt("intFieldName");
} finally {
selectStatement.close();
}
} catch (SQLException e1) {
// Log the error here
}
}
If you want to use this data in velocity you'll need to create a viewtool. Read more about that here: http://dotcms.com/docs/latest/DynamicPluginsViewtool