Mage::getModel but from another database don't work - database

I've managed to create a module that can connect to a second database next that one from the shop. It started an setup script to create the new table and I inserted one test data.
So far so good.
Now I want to get that data inside an observer.
I can get the model and the collection. Bbut when I count that collection it returns null. When I try getSelectSql(true) on that model that query looks like:
SELECT `main_table`.* FROM `custom_table` AS `main_table`
Running that query in the database returns my added test data.
app/etc/local.xml
<config>
<global>
<resources>
<external_db>
<connection>
<host><![CDATA[127.0.0.1]]></host>
<username><![CDATA[db_user]]></username>
<password><![CDATA[db_pass]]></password>
<dbname><![CDATA[external_db]]></dbname>
<active>1</active>
</connection>
Observer
public function validateRequest(Varien_Event_Observer $observer) {
try {
$collection = Mage::getModel('custom_module/custom_table')->getCollection();
$items = $collection->getItems();
That returns me the following exception:
SQLSTATE[42S02]: Base table or view not found: 1146 Table 'shop.custom_table' doesn't exist, query was: SELECT main_table.* FROM custom_table AS main_table
It looks like magento isn't able to choose the correct connection.
But I can't find the way to change that in a magento way.
The only way it works is:
$resource = Mage::getSingleton('core/resource');
$conn = $resource->getConnection('externaldb_read');
$results = $conn->query('SELECT * FROM custom_table');
I would like to do it without creating raw queries.

use setConnection() method before you load your collection. The Argument should be a valid core/resource object with your database selected.

Related

Laravel relationship always returning empty array

I have two models in a Laravel application Ft and Fi.
Ft contains the following code:
protected $table = 'ft';
protected $connection = 'XXX';
protected $keyType = 'string';
public function lines()
{
return $this->hasMany('App\Fi', 'ftstamp', 'ftstamp');
}
Fi contains the following code:
protected $table = 'fi';
In my controller I have the following code
Ft::select($fields)->with(['lines'])
All results have "lines": []
Relationship exists in database.
Database is SQL Server
ft.ftstamp and fi.ftstamp field is type char.
Driver used for connection is sqlsrv.
I'm sure this is a duplicate, but I can't find it. If you only select certain fields from the table, ensure that the primary key is one of them. The eager load is done as a separate query, not a join, so the key values have to be available.
For example, this code:
User::select(["id", "name"])->with("posts")->get();
Runs two database queries:
SELECT id, name FROM users;
SELECT * FROM posts WHERE user_id IN (?, ?, ?, ?...);
The second query is populated with the id values from the first. Without those values, the second query can't be run.
In a normal database, this would mean making sure that the array $fields contains "id" as an element, and I'd provide a code sample. Your database looks frightening however, so I won't try.

How to modify the DACPAC model at build time?

I want to alter the table model during build time in my BuildContributor. Here is some sample code:
using Microsoft.SqlServer.Dac.Deployment;
using Microsoft.SqlServer.Dac.Extensibility;
using Microsoft.SqlServer.Dac.Model;
using System.Collections.Generic;
using System.Linq;
namespace MyNamespace
{
[ExportBuildContributor("MyNamespace.MyBuildContributor", "1.0.0.0")]
public class MyBuildContributor : BuildContributor
{
protected override void OnExecute(BuildContributorContext context, IList<ExtensibilityError> messages)
{
foreach (var table in context.Model.GetObjects(DacQueryScopes.UserDefined, ModelSchema.Table))
{
var tableName = table.Name.Parts.Last();
var rowId = "alter table " + tableName + " add rowid uniqueidentifier";
context.Model.AddObjects(rowId);
}
}
}
}
The build succeeds with no errors but I don't see rowid in any of the tables when I go look in the model.xml file in bin\Debug\MyDb.dacpac.
You can't use Model.AddObjects in this context.
Model.AddObjects from (https://msdn.microsoft.com/en-us/library/microsoft.sqlserver.dac.model.tsqlmodel.addobjects(v=sql.120).aspx#M:Microsoft.SqlServer.Dac.Model.TSqlModel.AddObjects(System.String)):
"Adds objects to the model based on the contents of a TSql Script string. The script should consist of valid TSql DDL statements. Objects added using this method cannot be updated or deleted at a later point as update/delete requires a script name to be specified when adding the objects. If this is a requirement use the AddOrUpdateObjects method instead."
I.E it can only add objects like tables or stored procedure, columns by themselves aren't added to the model.
If you want to update an existing object (i.e. to add a column to an existing table) you will need to use "TSqlModel.AddOrUpdateObjects" which also takes a script name. You can get the script name from a build contributor by using:
var sourceName = table.GetSourceInformation().SourceName;
Then you can build the updated script you want (just a rough outline of rebuilding the SQL for stack overflow, I'm sure you can do better):
var sql = table.GetScript();
sql = sql.Trim().TrimEnd(')', ';') + ", rowid uniqueidentifier);";
var sourceName = table.GetSourceInformation().SourceName;
model.AddOrUpdateObjects(sql, sourceName, new TSqlObjectOptions());
There are a few ways you could create your new script but basically what you need is a new script which has your extra column and the original table definition which you can pass to AddorUpdateObjects to overwrite the original create table statement.
If you don't get a source to use in AddorUpdateObjects then maybe you could use a post-deploy script to add it to any table you need and then use a deployment contributor to remove the drop column step.
You could also look at using a deployment contributor instead to add the new column step to that.
Hope it helps! Let me know how you get on :)

using WPDB to display external database-data inside a WP-shortcode

I'm trying to figure out a way to use WPDB to load a whole row or single cells/fields from another table (not the Wordpress-DB) and displaying them in a shortcode. I have a bunch of weatherdata-values, I need the latest row (each column is another data-type (temp, wind, humidity, etc) of the database for a start.
Sadly, the plugin that would do everything that I need, SQL Shortcode, doesn't work anymore. I found this now:
https://de.wordpress.org/plugins/shortcode-variables/
Though I still need to use some PHP/PDO-foo to get the data from the database.
By heavy copy&pasting I came up with this:
<?php
$hostname='localhost';
$username='root';
$password='';
$dbname='sensordata';
$result = $db->prepare(SELECT * FROM `daten` WHERE id=(SELECT MAX(id) FROM `daten`););
$result->execute();
while ($row = $result->fetch(PDO::FETCH_ASSOC))
{
$data = $row['*'];
}
echo $data;
?>
But obviously it's not working. What I need to get it done with WPDB?
kind regards :)
Just in case anyone else needs this in the future. I used this now:
//connect to the database
<?php
$dbh = new PDO('mysql:host=localhost;dbname=databasename', 'dbuser',
'dbpasswort');
//query the database "databasename", selecting "columnname" from table "tablename", checking that said column has no NULL entry, sort it by column "id" (autoincrementing numeric ID), newest first and just fetch the last one
$sth = $dbh->query("SELECT `columnname` FROM `tablename` WHERE `columnname` IS NOT NULL order by id desc limit 1")->fetchColumn(0);
//print the value/number
print_r($sth);
?>
By using "SELECT colum1, colum2,... FROM" You should get all the columns, could be that fetchColumn needs to be replaced with something different though.

PostgreSQL query not working in Yii2

I want to execute query in my yii2 application. I'm using PostgreSQl. There is a table called list inside the user schema. If I try to build any query it returns 1. My code is here:
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list"
')->execute();
Please show me my mistake in the query above.
This is not related to the DB type in Yii2 if you want the result of a single value you should use queryScalar() instead of execute()
$numUsers = Yii::$app->db->createCommand('
SELECT COUNT(*) FROM "user"."list" ')->queryScalar();

SQL Server CE database and ADO.Net Entity Framework - data not saving

I have a SQL Server CE database file and I have ADO.NET Entity Framework object named History. I perform the following to get the latest ID:
var historyid = (from id in db.Histories // Get the current highest history Id
select (Int32?)(id.Id)).Max();
HistoryID = Convert.ToInt32(historyid);
if (HistoryID == 0) // No current record exists
{
HistoryID = 1; // Set the starter history Id
}
(Not the best way, but it is just to test).
This works well and returns the correct value (If I manually enter an ID of 1, it returns 1, same with 2 etc..)
The issue is with the following code:
History history = new History();
history.Id = 1;
history.SoftwareInstalled = "test";
db.AddToHistories(history);
db.SaveChanges();
The above works and runs through fine, but the changes are not saved to the database! Why is this?
Here is my db variable: dbDeSluggerEntities db = new dbDeSluggerEntities();
Thanks.
Edit: Here is an update: I noticed when I run the program and debug it, it shows that a history has been created and inserted and also gives an error of the primary key already existing, this happens each time I run the application (over and over). However, when I go to server explorer and right click the db and select 'Show Table Data' it shows no data.. When the program is run again, there is no primary key error or history's showing in the debug!
I was having exactly the same problem. By default the database is copied into your bin folder when you run the app and that is used.
My solution was to go into the properties of the db and set it to never copy and to put a full file path to the database in the connection string in the apps config file.

Resources