How do you reference a Django class name into a function? - django-models

I've written a function that returns the insert string for one class within Django that models and maps a table in FileMaker.
#staticmethod
def get_insert_string():
fields = []
arguments = []
for field in Owner._meta.fields:
if field.primary_key:
pass
elif field.help_text:
fields.append('"%s"' % field.help_text)
arguments.append('?')
result = 'insert into %s ( %s ) values ( %s )' % ( Owner.filemaker_table_name, u','.join(fields), u','.join(arguments))
return result
Example output.
Owner.get_insert_string()
u'insert into owner ( "uuid","ABN_number","Address_1","Creation_Date","Creation_Time","Creation_User","Creation_timestamp","Date_started","Modification_timestamp","State","Suburb","account_code","account_name","account_number","authorised_officer_first_name","authorised_officer_signature","authorised_officer_surname","bank_name","bsb","company_name","company_use_as_address","crn_number","discount_percent","driver_or_staff","fax","is_driver","is_staff","jp_name","jp_number","jp_signature","landline","mobile","oa_number","owner_1_first_name","owner_1_middle_name","owner_1_surname","owner_2_first_name","owner_2_middle_name","owner_2_surname","owner_3_first_name","owner_3_middle_name","owner_3_surname","paid_always","parts_at_cost","post code","purchase_order_required","shareholder","status","taxable","taxable_export","thirty_day_account","trade_retail_for_parts_cost","tsl_number","tsl_owner","updated_date" ) values ( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? )'
How could this be changed so the name of the class could be passed in and get the same results so that the function could be used for all the classes in the module?
Something like
def get_insert_string(class_name):
fields = []
arguments = []
for field in class_name._meta.fields:
if field.primary_key:
pass
if field.help_text:
fields.append('"%s"' % field.help_text)
arguments.append('?')
result = 'insert into %s ( %s ) values ( %s )' % ( class_name.filemaker_table_name, u','.join(fields), u','.join(arguments))
return result
where class_name maps into the matching Django class.

Discovered globals() mostly covers it.
Function example.
def get_insert_string(class_reference):
fields = []
arguments = []
for field in class_reference._meta.fields:
if field.primary_key:
pass
elif field.help_text:
fields.append('"%s"' % field.help_text)
arguments.append('?')
result = 'insert into %s ( %s ) values ( %s )' % ( class_reference.filemaker_table_name, u','.join(fields), u','.join(arguments))
return result
Calling example:
depot_maestro.models.get_insert_string(globals()['DriverShiftPreference'])
Results example:
insert into driver_shift_preferences ( "DEPOT_ID","driver_id","roster_template_id","roster_template____shift_slot_id","vehicle_id","uuid","commission_percentage","drive_name_lookup","lease_fee","levy_1","levy_2","linked_to_id","note","selected","shift_slot","week_id","creation_account_name","created_timestamp","modification_account_name","modification_timestamp" ) values ( ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,? )'
Only issue remaining is how to reference a class where the same class name exists in different modules.

Related

Postgresql: Custom Type + Arrays combination

I'm unable to find where the issue is for the below program. the values of the custom type are displaying without any errors when I use RAISE NOTICE statements at the end. When I run the final select statement, the error is Array value must start with "{" or dimension information. Please help me with the select statement on how to call the package/function.
create
or
replace TYPE t_col_foo as object
(
ID NUMBER
, CLUSTERNAME VARCHAR2(300)
, "1200AM" varchar2(10));
create
or
replace TYPE T_COL_R AS TABLE OF t_col_foo;
CREATE OR REPLACE PACKAGE foo_avail_pkg
IS
FUNCTION foo_slots
(
p_ref_data anyarray
)
RETURN t_col_r[];
END foo_avail_pkg;
CREATE OR REPLACE PACKAGE BODY foo_avail_pkg
IS
FUNCTION foo_slots
(
p_ref_data anyarray
)
RETURN t_col_r[]
IS
-- declare
r_target_data t_col_foo:=t_col_foo(null,null,null);
r_target_data_1 t_col_foo;
r_source_data text[];
t_return t_col_tab1;
BEGIN
t_return:=t_col_tab1();
select
array
(
select
unnest( p_ref_data )
)
into r_source_data
;
-- r_target_data = '{}';
for i in coalesce(array_lower(r_source_data,1),0) .. coalesce(array_upper(r_source_data,1),0)
LOOP
r_target_data.ID := substr(r_source_data[i],1,instr(r_source_data[i],',',1,1)-1);
r_target_data.CLUSTERNAME := substr(r_source_data[i],length(r_target_data.ID)+2,(instr(r_source_data[i],',',length(r_target_data.ID)+1,2) - instr(r_source_data[i],',',1,1))-1);
r_target_data."1200AM" := 3;
r_target_data_1 :=row(r_target_data.ID ,r_target_data.CLUSTERNAME,r_target_data."1200AM") :: t_col_foo;
END LOOP;
-- dbms_output.put_line(r_target_data_1);
RETURN r_target_data_1;
end;
END foo_avail_pkg;
This is how I have to call
select * from foo_avail_pkg.foo_SLOTS(array
(
select
ID
||','
||CLUSTER_NAME
||','
||LOB
from
y limit 1
));
And the error is
ERROR: malformed array literal: "(1398,Sanity20feb,3)"
DETAIL: Array value must start with "{" or dimension information.

How to create an array of pointers to objects in Matlab?

I'm writing a Matlab script where I have a bunch of objects of a same self defined class, say A, B and C. Then I have a function that work on any of the 2 objects, like func(A,B).
Now I want to pick an object, say A, and then func(A,x) through all the other objects. So basically achieve something like:
func(A,B)
func(A,C)
A.update()
func(B,A)
func(B,C)
B.update()
...
So I need to create an array of all the objects I can loop through, while excluding itself of course. I tried to do it with cell array, so I have:
AllObjs = {A,B,C}
for i=1:length(AllObjs)
if ~isequal(A, AllObjs{i})
func(A, AllObjs{i})
end
end
A.update()
However, when A is updated, the A in AllObjs doesn't get updates. So for the next loop I have to create a new array of all the objects. It's doable in this simple example but not manageable when the objects get updated elsewhere. So I would like to have an array of pointers to all the objects. My Google search tells me there's no pointer in Matlab, but is there a way to achieve what I want to do here?
I suspect (its difficult without seeing your code) your classes A, B & C do not inherit from from handle.
Take the examples below:
classdef noHandle
properties
name = '';
end
methods
function obj = noHandle ( name )
obj.name = name;
end
end
end
A = noHandle ( 'A' );
B = noHandle ( 'B' );
C = noHandle ( 'C' );
allObjs = { A B C }
allObjs{1}.name % check its name is "A"
% change the name of A
A.name = 'AAA'
allObjs{1}.name % see that allObjs{1} is still A.
However if you do:
classdef fromHandle < handle
properties
name = '';
end
methods
function obj = fromHandle ( name )
obj.name = name;
end
end
end
Then do:
A = fromHandle ( 'A' );
B = fromHandle ( 'B' );
C = fromHandle ( 'C' );
allObjs = { A B C }
allObjs{1}.name % check its name is "A"
% change the name of A
A.name = 'AAA'
allObjs{1}.name % see that allObjs{1} is updated to AAA.

Anorm SQL Folding a List into a class result

please pardon the level of detail. I'm not completely sure how to phrase this question.
I am new to scala and still learning the intricacies of the language. I have a project where all the data I need is contained in a table with a layout like this:
CREATE TABLE demo_data ( table_key varchar(10), description varchar(40), data_key varchar(10), data_value varchar(10) );
Where the table_key column contains the main key I'm searching on, and the description repeats for every row with that table_key. In addition there are descriptive keys and values contained in the data_key and data_value pairs.
I need to consolidate a set of these data_keys into my resulting class so that the class will end up like this:
case class Tab ( tableKey: String, description: String, valA: String, valB: String, valC: String )
object Tab {
val simple = {
get[String]("table_key") ~
get[String]("description") ~
get[String]("val_a") ~
get[String]("val_b") ~
get[String]("val_c") map {
case tableKey ~ description ~ valA ~ valB ~ valC => Tab(table_key, description, valA, valB, valC)
}
}
def list(tabKey: String) : List[Tab] = {
DB.withConnection { implicit connection =>
val tabs = SQL(
"""
SELECT DISTINCT p.table_key, p.description,
a.data_value val_a,
b.data_value val_b,
c.data_value val_c
FROM demo_data p
JOIN demo_data a on p.table_key = a.table_key and a.data_key = 'A'
JOIN demo_data b on p.table_key = b.table_key and b.data_key = 'B'
JOIN demo_data c on p.table_key = c.table_key and c.data_key = 'C'
WHERE p.table_key = {tabKey}
"""
).on('tabKey -> tabKey).as(Tab.simple *)
}
return tabs
}
}
which will return what I want, however I have more than 30 data keys that I wish to retrieve in this manner, and the joins to itself rapidly becomes unmanageable. As in the query ran for 1.5 hours and used up 20GB worth of temporary tablespace before running out of disk space.
So instead I am doing a separate class that retrieves a list of data keys and data values for a given table key using the "where data_key in ('A','B','C',...)", and now I'd like to "flatten" the returned list into a resulting object that will have the valA, valB, valC, ... in it. I still want to return a list of the flattened objects to the calling routine.
Let me try to idealize what I'd like to accomplish..
Take a header result set and a detail result set, extract out the keys out of the detail result set to populate additional elements/properties in the header result set and produce a list of classes containing the all the elements of the header result set, and the selected properties from the detail result set. So I get a list of TabHeader(tabKey,Desc) and for each I retrieve a list of interesting TabDetail(DataKey,DataValue), I then extract out the element where the DataKey == 'A' and put the DataValue element in Tab(valA), and do the same for DataKey == 'B', 'C', ... After I'm done I wish to produce a Tab(tabKey, Desc, valA, valB, valC, ...) in place of the corresponding TabHeader. I could quite possibly muddle through this in Java, but I'm treating this as a learning opportunity and would like to know a good way to do this in Scala.
I'm feeling that something with the scala mapping should do what I need, but I haven't been able to track down exactly what.

Django Field Choices

Given below is my Model definition and I have added this module part of the Admin. I'm trying to create new row and while selecting value '3' or any other value for Duration field(listed as select fields), I get the following error.- "Value 3 is not a valid choice".
Please provide your inputs.
Model Definition
NO_OF_HRS = (
('1','One'),
('2','Two'),
('3','Three'),
('4','Four'),
('5','Five'),
('6','Six'),
('7','Seven'),
('8','Eight'),
('9','Nine'),
('10','Ten'),
('11','Eleven'),
('12','Twelve'),
)
YR_MONTH = (
("Y", "Year"),
("M", "Month"),
)
POS_STATUS = (
("A", "Active"),
("C", "Closed"),
)
datecreated = models.DateTimeField()
volposition = models.CharField(max_length=300)
roledesc = models.CharField(max_length=5000)
noofhours = models.IntegerField(blank = True,null = True)
Qualreqt = models.CharField(max_length=8000)
Duration = models.IntegerField(choices=NO_OF_HRS,blank = True,null = True)
Durationyrmon = models.CharField(choices=YR_MONTH,max_length=10)
posstatus = models.CharField(choices=POS_STATUS,max_length=1)
teamrelation = models.CharField(max_length=50)
When you use choices, the first value of the tuple is the value that will be stored in the database and the second value is the value that will be shown in the admin.
In NO_OF_HRS the values are strings (for example '1', '2') but it is a models.IntegerField so the values should be integers. That's why you're now getting an error.
Opened a ticket on django with fix and dirty fix:
https://code.djangoproject.com/ticket/24897

Perl - Hash of Arrays across Module

I am a bit new to Perl and I need some help regarding moving my Hash of Arrays across Modules.
Currently I have a db module that stores an array like so:
sub getSourceCriteria {
my($self) = shift();
my($sourceId) = shift();
chomp $sourceId;
my(%criteria) =();
$logger->debug("Getting records for Source ID: " . $sourceId);
$dbh=DBI->connect('dbi:ODBC:StkSkrnDB', 'RTETET', 'XXuser01',{ RaiseError => 1, AutoCommit => 0 }) || \
$logger->err_die("Database connection not made: $DBI::errstr\n");
my($sth) = "select a.criteria_id, a.criteria_type, a.criteria_props,a.generalcriteria_id,b.field_id ";
$sth = $sth . "from t_criteria a, t_sourceMapping b where a.generalcriteria_id = (select generalcriteria_id from t_sourcecriteria where source_id =?) ";
$sth = $sth . "and a.criteria_id=b.criteria_id";
my($qry) = $dbh->prepare($sth);
$qry->execute($sourceId) || $logger->error("Could not query for Source Criteria: $DBI::errstr\n");
my(#row)=();
my($tempCount) = 0;
while ( #row = $qry->fetchrow_array ) {
$tempCount = scalar #row;
$logger->debug("Size of retrieved SQL Array : $tempCount");
$criteria{$row[0]} = \#row;
###{$criteria{$row[0]} } = \#row;
}
return %criteria;
}
And I have a seperate perl script that reads the SQL output from the code above:
foreach my $criteria (keys %criterias) {
#temp = exists( $criterias{$criteria} ) ? #{ $criterias{$criteria} } : ();
##my $tempStr = exists( $criterias{$criteria} ) ? "Yes" : "No";
$arraySize = scalar #temp;
$logger->debug("GENERALCRITERIA_ID is $GENERALCRITERIA_ID and size of array is $arraySize and $temp[0]");
$genCrit_ID = $temp[$GENERALCRITERIA_ID];
$logger->debug("Criteria ID $criteria has Gen Criteria ID $genCrit_ID");
if (0!=$generalCriteria_ID || $generalCriteria_ID != $genCrit_ID ) { ## test for uniqueness
$generalCriteria_ID = -1;
}
else {
$generalCriteria_ID = $genCrit_ID;
}
}# do something with $key and $value
$generalCriteria = $generalCriteria_ID;
}
The problem is I keep getting 0 as the retrieved array size( 2nd snippet) even though when I store the array ( in the 1st snippet ) I check and get the actual array size.
Please any help/clarification would be greatly appreciated.
EDIT
Added more code in the DB interface code.
In your while loop, you are assigning to #row and then storing a reference to that array. However, each time the loop iterates, you are replacing the contents of #row without declaring a new array. So at the end, each of your references point towards the same thing.
In your code here:
my(#row)=();
my($tempCount) = 0;
while ( #row = $qry->fetchrow_array ) {
$tempCount = scalar #row;
$logger->debug("Size of retrieved SQL Array : $tempCount");
$criteria{$row[0]} = \#row;
###{$criteria{$row[0]} } = \#row;
}
Each time the while loop iterates, you assign new values to the #row array. But since the my(#row)=(); line occurs outside of the loop, the #row array is always the same. So each time you assign to the array, you are changing what is stored in all of the references you have already taken.
To fix the problem, you need to declare a new array for each iteration. The simplest way to do this is to move the declaration into the while condition:
my($tempCount) = 0;
while ( my #row = $qry->fetchrow_array ) {
$tempCount = scalar #row;
$logger->debug("Size of retrieved SQL Array : $tempCount");
$criteria{$row[0]} = \#row;
###{$criteria{$row[0]} } = \#row;
}
Now each time you take the reference \#row you will be getting a reference to a new array.
If your $qry->fetchrow_array method returned an array reference, you would not have had the issue:
my $row;
while ($row = $qry->fetchrow_array) {
$logger->debug("Size of retrieved SQL Array : ".#$row);
$criteria{$$row[0]} = $row; # already a reference
}
But I would still write that as while (my $row = ... in my own code, since keeping scopes small is a good thing.

Resources